Está en la página 1de 81

Descripcin General del PIC16F877

2.- Descripcin General del PIC16F877


2.1.- La Familia del PIC16F877
El microcontrolador PIC16F877 de Microchip pertenece a una gran familia de
microcontroladores de 8 bits (bus de datos) que tienen las siguientes
caractersticas generales que los distinguen de otras familias:
-

Arquitectura Harvard
Tecnologa RISC
Tecnologa CMOS

Estas caractersticas se conjugan para lograr un dispositivo altamente eficiente en


el uso de la memoria de datos y programa y por lo tanto en la velocidad de
ejecucin.
Microchip ha dividido sus microcontroladores en tres grandes subfamilias de
acuerdo al nmero de bits de su bus de instrucciones:
Subfamilia
Base - Line
Mid Range
High - End

instrucciones
33 instrucciones de12 bits
35 instrucciones de 14 bits
58 instrucciones de 16 bits

nomenclatura
PIC12XXX y PIC14XXX
PIC16XXX
PIC17XXX y PIC18XXX

Existen algunas excepciones, como el PIC16C5X que maneja 33 instrucciones


de 12 bits (posee empaquetados de 18 y 28 pines y se energiza con 2.5 volts)
Algunos autores manejan una gama enana consistente en los PIC12C508 y
PIC12C509 en empaque de 8 patitas y con un bus de instrucciones de 12 o de
14 bits.

Variantes principales
Los microcontroladores que produce Microchip cubren una amplio rango de
dispositivos cuyas caractersticas pueden variar como sigue:
-

Empaquetado (desde 8 patitas hasta 68 patitas)


Tecnologa de la memoria includa (EPROM, ROM, Flash)
Voltajes de operacin (desde 2.5 v. Hasta 6v)
Frecuencia de operacin (Hasta 20 Mhz)

Empaquetados
Aunque cada empaquetado tiene variantes, especialmente en lo relativo a las
dimensiones del espesor del paquete, en general se pueden encontrar paquetes
tipo PDIP (Plastic Dual In Line Package), PLCC (Plastic Leaded Chip Carrier),

Descripcin General del PIC16F877


QFP (Quad Flat Package) y SOIC (Small Outline I.C.) los cuales se muestran en
las figuras siguientes :

PDIP

SOIC

Descripcin General del PIC16F877


Algunos Empaquetados de Circuito Integrado:

DIP (Dual In-Line Package)


= DIL (Dual In-Line)

PLCC (Plastic Leaded Chip Carrier)


LCC (Leaded Chip Carrier)

QFP (Quad Flat Pack)


PQFP (Plastic Quad Flat Pack
Lidded)
TQFP (Thin Quad Flat Pack)

SOIC (Small Outline IC Gull


Wing Style)
SSOP (Shrunk Small Outline
Package)
TSSOP (Thin Shrunk Small
Outline Package)

Numeracin de patitas en diferentes empaquetados:

DIL package

PLCC package

QFP package

PGA package

This numbering method is used for


these packages:
DIL (Dual In-Line)
DIP (Dual In-line Package)
SDIP (Shrink Dual In-line Package)
SO (Small Outline)
SOIC (Small Outline Integrated Circuit)
SOJ (Small Outline J-leaded)
SOP (Small Outline Package)
SSOP (Shrink Small Outline Package)
TSOP (Thin Small Outline Package)

This numbering method is


used for these packages:
PLCC (Plasic Leaded Chip
Carrier)
QFP (Quad Flat Package)
used by Motorola
PQFP (Plasic Quad Flat
Package) used by Motorola

This numbering method is used


for these packages:
QFP (Quad Flat Package)
PQFP (Plasic Quad Flat
Package)
PLCC (Plasic Leaded Chip
Carrier) used by Intel

This numbering method


is used for these
packages:
BGA (Ball Grid Array)
PGA (Pin Grid Array)

Nomenclatura
Adems de lo mostrado en la tabla anterior, en el nombre especfico del
microcontrolador pueden aparecer algunas siglas que dependen del rango de
voltaje manejado y del tipo de memoria ROM incluida, como se muestra en la
siguiente tabla:
Tipo de memoria
EPROM, OTP
ROM
Flash

Rango de voltaje
Estndar (4.5 a 6 volts)
Extendido (2.5 a 6 volts)
PIC16CXXX
PIC16LCXXX
PIC16CRXXX
PIC16LCRXXX
PIC16FXXX
PIC16LFXXX

Descripcin General del PIC16F877


Oscilador
Los PIC de rango medio permiten hasta 8 diferentes modos para el oscilador. El
usuario puede seleccionar alguno de estos 8 modos programando 2 bits de
configuracin del dispositivo denominados: FOSC1 y FOSC0, ubicados en un
registro especial de configuracin en la localidad 2007H de la memoria de
programa:
Configuration word (2007H):
13

12

11

10

_________

CP1 CP0 DEBUG - WRT CPD LVP BODEN CP1 CP0 PWRTE WDTE FOSC1 FOSC0

En algunos de estos modos el usuario puede indicar que se genere o no una


salida del oscilador (CLKOUT) a travs de una patita de Entrada/Salida. Los
modos de operacin se muestran en la siguiente lista:
FOSC1
0
0
1
1

FOSC0
0
1
0
1

LP
XT
HS
RC

Modo de operacin del oscilador


Baja frecuencia (y bajo consumo de potencia)
Cristal / Resonador cermico externos, (Media frecuencia)
Alta velocidad (y alta potencia) Cristal/resonador
Resistencia / capacitor externos

Obs: Algunos PICs poseen un modo de oscilacin que les permite usar una
resistencia y un capacitor interno calibrados para 4 Mhz.

Los tres modos LP, XT y HS usan un cristal o resonador externo, la diferencia sin
embargo es la ganancia de los drivers internos, lo cual se ve reflejado en el rango
de frecuencia admitido y la potencia consumida. En la siguiente tabla se muestran
los rangos de frecuencia as como los capacitores recomendados para un
oscilador en base a cristal.
Modo

Frecuencia tpica

LP

32 khz
200 khz
100 khz
2 Mhz
4 Mhz
8 Mhz
10 Mhz
20 Mhz

XT
HS

Capacitores recomendados
C1
C2
68 a 100 pf
15 a 30 pf
68 a 150 pf
15 a 30 pf
15 a 30 pf
15 a 30 pf
15 a 30 pf
15 a 30 pf

68 a 100 pf
15 a 30 pf
150 a 200 pf
15 a 30 pf
15 a 30 pf
15 a 30 pf
15 a 30 pf
15 a 30 pf

Descripcin General del PIC16F877


Cristal externo: En los tres modos mostrados en la tabla anterior se puede usar
un cristal o resonador cermico externo. En la siguiente figura se muestra la
conexin de un cristal a las patitas OSC1 y OS2 del PIC.
OSC1
C1

A la lgica interna

SLEEP

XTAL

Rf

C2

A la lgica interna

OSC2

Circuito RC externo: En los modos RC y EXTRC el PIC puede generar su seal


oscilatoria basado en un arreglo RC externo conectado a la patita OSC1 como se
muestra en la siguiente figura:

Vdd

Rext

Fosc

OSC1

Reloj interno

Cext

Fosc/4

OSC2

Este modo slo se recomienda cuando la aplicacin no requiera una gran


precisin en la medicin de tiempos.
Rangos.- La frecuencia de oscilacin depende no slo de los valores de Rext y
Cext, sino tambin del voltaje de la fuente Vdd. Los rangos admisibles para
resistencia y capacitor son:
Rext: de 3 a 100 Kohms
Cext: mayor de 20 pf
Oscilador externo.- Tambin es posible conectar una seal de reloj generada
mediante un oscilador externo a la patita OSC1 del PIC. Para ello el PIC deber
5

Descripcin General del PIC16F877


estar en uno de los tres modos que admiten cristal (LP, XT o HS). La conexin se
muestra en la siguiente figura:

Seal externa

OSC1

OSC2

Resistencia a tierra
para reducir ruido

Oscilador interno de 4Mhz.- En los PICs que poseen este modo de oscilacin,
(modo INTRC) el PIC usa un arreglo RC interno que genera una frecuencia de 4
Mhz con un rango de error calibrable de 1.5%. Para calibrar el error de
oscilacin se usan los bits CAL3, CAL2 , CAL1 Y CAL0 del registro OSCCAL.
Calibracin del oscilador interno.- El fabricante ha colocado un valor de
calibracin para estos bits en la ltima direccin de la memoria de programa. Este
dato ha sido guardado en la forma de una instruccin RETLW XX. Si no se quiere
perder este valor al borrar el PIC (en versiones EPROM con ventana) primero se
deber leer y copiar. Es una buena idea escribirlo en el empaquetado antes de
borrar la memoria).
2.2.- Caractersticas generales del PIC16F877
La siguiente es una lista de las caractersticas que comparte el PIC16F877 con los
dispositivos ms cercanos de su familia:
PIC16F873

PIC16F874

PIC16F876

PIC16F877

CPU:
- Tecnologa RISC
- Slo 35 instrucciones que aprender
- Todas las instrucciones se ejecutan en un ciclo de reloj, excepto los saltos que
requieren dos
- Frecuencia de operacin de 0 a 20 MHz (200 nseg de ciclo de instruccin)
- Opciones de seleccin del oscilador
Memoria:
- Hasta 8k x 14 bits de memoria Flash de programa
- Hasta 368 bytes de memoria de datos (RAM)
- Hasta 256 bytes de memoria de datos EEPROM

Descripcin General del PIC16F877


- Lectura/escritura de la CPU a la memoria flash de programa
- Proteccin programable de cdigo
- Stack de hardware de 8 niveles
Reset e interrupciones:
- Hasta 14 fuentes de interrupcin
- Reset de encendido (POR)
- Timer de encendido (PWRT)
- Timer de arranque del oscilador (OST)
- Sistema de vigilancia Watchdog timer.
Otros:
- Modo SLEEP de bajo consumo de energa
- Programacin y depuracin serie In-Circuit (ICSP) a travs de dos patitas
- Rango de voltaje de operacin de 2.0 a 5.5 volts
- Alta disipacin de corriente de la fuente: 25mA
- Rangos de temperatura: Comercial, Industrial y Extendido
- Bajo consumo de potencia:
o Menos de 0.6mA a 3V, 4 Mhz
o 20 A a 3V, 32 Khz
o menos de 1A corriente de standby (modo SLEEP).
Perifricos:
Perifrico
3 a 5 Puertos
paralelos
3 Timers

PIC16F873
PIC16F876
Timer0
Timer1

PIC16F874
PIC16F877
PortA,
B,C,D,E
Timer0
Timer1

Timer2

Timer2

PortA,B,C

Captura
Comparacin
PWM
1 Convertidor A/D AN0,...,AN4
SSP
Puertos Serie
USART/SCI
ICSP
Puerto Paralelo
PSP
Esclavo
2 mdulos CCP

Caractersticas
con lneas digitales programables individualmente

Captura
Comparacin
PWM
AN0,...,AN7
SSP
USART/SCI
ICSP
PSP

Contador/Temporizador de 8 bits con pre-escalador de 8 bits


Contador/Temporizador de 16 bits con pre-escalador
Contador/Temporizador de 8 bits con pre-escalador y postescalador de 8 bits y registro de periodo
16 bits, 1.5 nseg de resolucin mxima
16 bits, 200 nseg de resolucin mxima
10 bits
de 10 bits, hasta 8 canales
Puerto Serie Sncrono
Puerto Serie Universal
Puerto serie para programacin y depuracin in circuit
Puerto de 8 bits con lneas de protocolo

2.3.- Diagrama de Bloques del PIC16F877


En la siguiente figura se muestra a manera de bloques la organizacin interna del
PIC16F877, Se muestra tambin junto a este diagrama su diagrama de patitas,
para tener una visin conjunta del interior y exterior del Chip.

Descripcin General del PIC16F877

13

Memoria de
Programa en
FLASH

Program Counter

14
Bus de programa

Bus de datos

Archivo de
registros en
RAM

Stack de 3 niveles
(13 bits)

PORTA

Registro de
Instrucciones

Mux
Direc.
8 indirecto
Reg FSR

7
Direc. directo

PORTB

Reg STATUS

Decodificacin
de instrucciones
y control
Generacin de
tiempo

Timer de encendido
(PWRT)
Timer de aranque del
oscilador (OST)
Reset de encendido
(POR)
Timer del watchdog

3
Mux
PORTC

Timer0

ALU

Brown-out Reset

Programacin en
bajo voltaje

MCLR
VDD,VSS

Timer1

RB0/INT
RB1
RB2
RB3/PGM
RB4
RB5
RB6/PGC
RB7/PGD
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
RC7/RX/DT

Reg W

Depurador In-circuit

OSC1/CLKIN
OSC2/CLKOUT

RA0/AN0
RA1/AN1
RA2/AN2/VREFRA3/AN3/VREF+
RA4/T0CKI
RA5/AN4/SS

Memoria de
datos
EEPROM

Timer0

PORTD

Timer0

RD0/PSP0
RD1/PSP1
RD2/PSP2
RD3/PSP3
RD4/PSP4
RD5PSP5
RD6/PSP6
RD7/PSP7
RE0/AN5/RD

PORTE
Memoria de
datos
EEPROM

CCP1,2

RE1/AN6/WR
RE2/AN7/CS

Puerto Serie
Sncrono

USART

Descripcin General del PIC16F877


2.4.- Descripcin de la CPU
La CPU es la responsable de la interpretacin y ejecucin de la informacin
(instrucciones) guardada en la memoria de programa. Muchas de estas
instrucciones operan sobre la memoria de datos. Para operar sobre la memoria de
datos adems, si se van a realizar operaciones lgicas o aritmticas, requieren
usar la Unidad de Lgica y Aritmtica (ALU). La ALU controla los bits de estado
(Registro STATUS), los bits de este registro se alteran dependiendo del resultado
de algunas instrucciones.
Ciclo de instruccin
El registro Program Counter (PC) es gobernado por el ciclo de instruccin como se
muestra en la siguiente figura. Cada ciclo de instruccin la CPU lee (ciclo Fetch) la
instruccin guardada en la memoria de programa apuntada por PC y al mismo
tiempo ejecuta la instruccin anterior, esto debido a una cola de instrucciones
que le permite ejecutar una instruccin mientras lee la prxima:

Q1

Q2

Tcy1
Q3

Q4

Q1

Q2

Tcy2
Q3

Q4

OSC1
OSC2 / Tosc
CLKOUT
PC
Lee instruccin PC
Ejecuta instruccin PC-1

PC+1
Lee instruccin PC+1
Ejecuta instruccin PC

Como puede verse, cada ciclo de instruccin (Tcy = 4Tosc) se compone a su vez de
cuatro ciclos del oscilador (Tosc= 1/Fosc)). Cada ciclo Q provee la sincronizacin
para los siguientes eventos:
Q1: Decodificacin de la instruccin
Q2: Lectura del dato (si lo hay)
Q3: Procesa el dato
Q4: Escribe el dato
Debido a esto cada ciclo de instruccin consume 4 ciclos de reloj, de manera que
si la frecuencia de oscilacin es Fosc, Tcy ser 4/Fosc.
Registros de la CPU.
Registro PC.- Registro de 13 bits que siempre apunta a la siguiente instruccin a
ejecutarse. En la siguiente seccin se dan mayores detalles en el manejo de este
registro.

Descripcin General del PIC16F877


Registro de Instruccin.- Registro de 14 bits. Todas las instrucciones se colocan
en l para ser decodificadas por la CPU antes de ejecutarlas.
Registro W.- Registro de 8 bits que guarda resultados temporales de las
operaciones realizadas por la ALU
Registro STATUS.- Registro de 8 bits, cada uno de sus bits (denominados
Banderas) es un indicador de estado de la CPU o del resultado de la ltima
operacin como se indica en la siguiente figura:
R/W-0

R/W-0

R/W-0

R-1

R-1

R/W-x

R/W-x

R/W-x

____

PD

DC

Bit 0

IRP

RP1

RP0

____

Bit 7

TO

* Notacin:
R= Bit leble W= Bit Escribible U= No implementado (se lee como 0)
-n= Valor despus del Reset de encendido
Z.- Este bit se pone (=1) para indicar que el resultado de la ltima operacin fue
cero, de lo contrario se limpia (=0)
C.- Bit de acarreo/prstamo de la ltima operacin aritmtica (en el caso de
prstamo (resta), el bit se invierte antes de guardarse)
__________ _

DC.- Acarreo/ prestamo proveniente del cuarto bit menos significativo. Funciona
igual que el bit C, pero para operaciones de 4 bits.
Las restas se realizan sumando el complemento a dos del segundo operando, por
ejemplo, para los datos 4FH y 25H:
Suma:
4FH
+25H
Resultado: 74 H
Bits C,DC:

0100 1111
+ 0100 0101
0 0111 0100
C=0, DC=1

Resta:
4FH
-25H
2AH

0100 1111
- 0100 0101

0100 1111
+ 1101 1011
1 0010 1010
C=0, DC=0

2.5.- Conjunto de Instrucciones de Rango Medio


En la siguiente tabla se resumen las 35 instrucciones que reconoce la CPU de los
PIC de medio rango, incluyendo su mnemnico, tiempo de ejecucin, cdigo de
mquina y afectacin de banderas:

10

Descripcin General del PIC16F877


Mnemnico
ADDWF f,d
ANDWF f,d
CLRF f
CLRW
COMF f,d
DECF f,d
DECFSZ f,d
INCF f,d
INCFSZ f,d
IORWF f,d
MOVF f,d
MOVWF f
NOP
RLF f,d
RRF f,d
SUBWF f,d
SWAPF f,d
XORWF f,d
BCF f,b
BSF f,b
BTFSC f,b
BTFSS f,b
ADDLW k
ANDLW k
CALL k
CLRWDT
GOTO k
IORLW k
MOVLW k
RETFIE
RETLW k
RETURN
SLEEP
SUBLW k
XORLW k

Descripcin

Ciclos

Cdigo de Mquina

Operaciones con el archivo de registros orientadas a bytes


00 0111 dfff ffff
1

Suma f + W
W AND f
Limpia f
Limpia W
Complementa los bits de f
Decrementa f en 1
Decrementa f, escapa si 0
Incrementa f en 1
Incrementa f, escapa si 0
W OR f
Copia el contenido de f
Copia contenido de W en f
No operacin
Rota f a la izquierda
Rota f a la derecha
Resta f W
Intercambia nibbles de f
W EXOR f

1
1
1
1
1
1(2)
1
1(2)
1
1
1
1
1
1
1
1
1

00 0101 dfff ffff


00 0001 1fff ffff
00 0001 0xxx xxxx
00 1001 dfff ffff
00 0011 dfff ffff

Banderas
afectadas

C,DC,Z
Z
Z
Z
Z
Z

00 1011 dfff ffff


00 1010 dfff ffff

00 1111 dfff ffff


00 0100 dfff ffff
00 1000 dfff ffff

Z
Z

00 0000 1fff ffff


00 0000 0xx0 0000
00 1101 dfff ffff
00 1100 dfff ffff
00 0010 dfff ffff

C
C
C,DC,Z

00 1110 dfff ffff


00 0110 dfff ffff

Operaciones con el archivo de registros orientadas a bits


01 00bb bfff ffff
Limpia bit b en f
1

Pone bit b en f
Prueba bit b en f, escapa si 0
Prueba bit b en f, escapa si 1

1
1(2)
1(2)

01 01bb bfff ffff


01 10bb bfff ffff
01 11bb bfff ffff

Operaciones con literales y de control del programa


11 111x kkkk kkkk
1

Suma literal k + W W
k AND W W
Llamado a subrutina
Limpia timer del watchdog
Salto a la direccin k
k OR W W
Copia literal a W
Retorna de interrupcin
Retorna con literal k en W
Retorna de subrutina
Activa Modo standby
Resta k W W
k EXOR W W

1
2
1
2
1
1
2
2
2
1
1
1

11 1001 kkkk kkkk

C,DC,Z
Z

10 0kkk kkkk kkkk


00 0000 0110 0100

____

____

TO , PD

10 1kkk kkkk kkkk


11 0000 kkkk kkkk

11 00xx kkkk kkkk


00 0000 0000 1001
11 01xx kkkk kkkk
00 0000 0000 1000
00 0000 0110 0011
11 110x kkkk kkkk
11 1010 kkkk kkkk

____

____

TO , PD

C,CD,Z
Z

d = 0 destino W
Notacin: d= destino del resultado
d = 1 destino registro
f =direccin del registro (memoria RAM), b= nmero de bit (0 a 7), k= dato de 8 bits

Descripcin de algunas instrucciones.


Para obtener la descripcin detallada de cada instruccin de la tabla anterior se
deber consultar la seccin 29 del manual del fabricante (PICmicro Mid-Range
MCU Reference Manual). A continuacin slo se ejemplificarn algunas
instrucciones con el propsito de clarificar la operacin que realizan.

11

Descripcin General del PIC16F877


Ejemplo 1.- Para realizar la suma y la resta mencionadas en la seccin anterior (4Fh+25h y 4Fh25h) se pueden usar las siguientes instrucciones:
Suma
...
Resta

MOVLW 0x4F
ADDLW 0x25

;carga el primer sumando en W


;suma W+25h y guarda el resultado en W

MOVLW 0x25
SUBLW 0x4F

;carga el sustraendo en W
;Resta 4Fh-W y guarda el resultado en W

En el siguiente ejemplo se ejemplifica el efecto de algunas instrucciones sobre el


registro W, sobre el registro de propsito general 20h de memoria RAM.
Ejemplo 2.- Se anota como comentario a un lado de cada instruccin como queda el contenido de
W, del registro 20h y de las banderas C, DC y Z:
inicio

MOVLW 0xF4
;W=F4h, 0x20= ??, C=?, DC=?, Z=?
ADDLW 0x0B
;W=FFh, 0x20= ??, C=0, DC=0, Z=0
MOVWF 0X20
;W=FFh, 0x20=FFh, C=0, DC=0, Z=0
INCF 0x20,1
;W=FFh, 0X20=00h, C=0, DC=0, Z=1
INCF 0X20,0
;W=01h, 0x20=00h, C=0, DC=0, Z=0
COMF 0X20,1
;W=01h, 0x20=FFh, C=0, DC=0, Z=0
XORWF 0x20,1
;W=01h, 0x20=FEh, C=0, DC=0, Z=0
MOVF 0x20,0
;W=FEh, 0x20=FEh, C=0, DC=0, Z=0
;(El ensamblador permite escribir esta ltima como MOVFW 0x20)
DECF 0x20,1
;W=FEh, 0x20=FDh, C=0, DC=0, Z=0
ANDWF 0x20,1
;W=FEh, 0x20=FCh, C=0, DC=0, Z=0
RLF 0x20,1
;W=FEh, 0x20=F8h, C=1, DC=0, Z=0
SWAPF 0x20,1
;W=FEh, 0x20=8Fh, C=1, DC=0, Z=0
BCF 0x20,3
;W=FEh, 0x20=87h, C=1, DC=0, Z=0
BSF 0x20,5
;W=FEh, 0x20=A7h, C=1, DC=0, Z=0

Formato General de las Instrucciones.


Cada instruccin en lenguaje de mquina (binario) del PIC contiene un cdigo de
operacin (opcode) el cual puede ser de 3 a 4 o 6 bits, dependiendo del tipo de
instruccin.
A continuacin se describe el formato para cada tipo de instruccin de los PIC de
rango medio:
Operaciones con el archivo de registros orientadas a bytes
13

Opcode

f (direccin del registro)

El bit d especifica el destino del resultado de la operacin:


d = 0: destino W
d = 1: destino f
f = direccin de 7 bits del archivo de registros.
12

Descripcin General del PIC16F877

Operaciones con el archivo de registros orientadas a bits


13

10

Opcode

7 6

b (bit #)

f (direccin del registro)

b : Especificacin en tres bits del bit sobre el que se va a operar


f = direccin de 7 bits del archivo de registros.
Operaciones con literales y de control
Formato general:
13

8 7

Opcode

k (Literal)

k : Literal = Valor de un operando de 8 bits


Formato para CALL y GOTO:
13

11 10

Opcode

k (Literal)

k : Literal = Valor de un operando de 8 bits

2.6.- Organizacin de la memoria del PIC


Los PIC tienen dos tipos de memoria: Memoria de Datos y Memoria de programa,
cada bloque con su propio bus: Bus de datos y Bus de programa; por lo cual cada
bloque puede ser accesado durante un mismo ciclo de oscilacin.
La Memoria de datos a su vez se divide en
-

Memoria RAM de propsito general


Archivo de Registros (Special Function Registers (SFR))

2.6.1.- La Memoria de Programa


Los PIC de rango medio poseen un registro Contador del Programa (PC) de 13
bits, capaz de direccionar un espacio de 8K x 14, como todas la instrucciones son
de 14 bits, esto significa un bloque de 8k instrucciones. El bloque total de 8K x 14
de memoria de programa est subdividido en 4 pginas de 2K x 14. En la
siguiente figura se muestra esta organizacin.

13

Descripcin General del PIC16F877


Direccin

0000h
...
0004h
0005h
...
07FFh

Vector de Reset
...
Vector de interrupcin
Pgina 0

0800h
...
0FFFh

Pgina 1

1000h
...
17FFh

Pgina 2

1800h
...
1FFFh

Pgina 3

Observacin1: No todos los PIC tienen implementado todo el espacio de 8K de


memoria de programa (Consultar las hojas de datos del PIC especfico).
Observacin2: El fabricante puede grabar datos de calibracin en localidades de
memoria de programa por lo que se debern anotar en papel antes de borrar los
dispositivos con ventana transparente.
Vector de Reset.- Cuando ocurre un reset el contenido del PC es forzado a cero,
sta es la direccin donde la ejecucin del programa continuar despus del reset,
por ello se le llama direccin del vector de reset.
Vector de interrupcin.- Cuando la CPU acepta una solicitud de interrupcin
ejecuta un salto a la direccin 0004h, por lo cual a sta se le conoce como
direccin del vector de interrupcin. El programador deber colocar en esta
direccin la Rutina de Atencin a la Interrupcin (Interrupt Service Routine
(ISR))., o bien un salto al inicio de ella.
El registro PCLATH no es modificado en esta circunstancia, por lo cual habr que
tener cuidado al manipular el registro PC (saltos y llamadas a subrutina) dentro de
la Rutina de Atencin a la Interrupcin
Manejo del Contador del Programa (PC)
El registro contador del programa (PC) especifica la direccin de la instruccin que
la CPU buscar (fetch) para ejecutarla.

14

Descripcin General del PIC16F877


El PC consta de 13 bits, separados en dos partes: como se muestra en la figura
siguiente
PCH
12

PCL
8

PC
El byte de orden bajo es llamado el registro PCL, mientras que el byte de orden
alto es llamado registro PCH. Este ltimo contiene los bits PC<12:8> y no se
puede leer o escribir directamente Todas las actualizaciones al registro PCH
deben ser hechas a travs del registro PCLATH.
En la siguiente figura se ilustran las cuatro situaciones y las maneras
correspondientes en que el PC puede ser actualizado.

Nota: PCLATH nunca es actualizado con el contenido de PCH

15

Descripcin General del PIC16F877


Paginacin
Para saltar entre una pgina y otra, los bits ms significativos del PC debern ser
modificados. Debido a que las instrucciones GOTO y CALL slo pueden
direccionar un bloque de 2K (pues usan una direccin de 11 bits) deben existir
otros dos bits que acompleten los 13 bits del PC para moverse sobre los 8K de
memoria de programa.
Estos dos bits extra se encuentran en un SFR denominado PCLATH (Program
Counter Latch High) en sus bits PCLATH<4:3>. Por esto antes de un GOTO o un
CALL el usuario deber asegurarse que estos bits apunten a la pgina deseada.
Si las instrucciones se ejecutan secuencialmente el PC cruza libremente los
lmites de pgina sin necesidad de que el usuario escriba en el PCLATH
Memoria de Stack
La memoria de stack es una area de memoria completamente separada de la
memoria de datos y la memoria de programa. El stack consta de 8 niveles de 13
bits cada uno. Esta memoria es usada por la CPU para almacenar las direcciones
de retorno de subrutinas. El apuntador de stack no es ni leble ni escribible.
Cuando se ejecuta una instruccin CALL o es reconocida una interrupcin el PC
es guardado en el stack y el apuntador de stack es incrementado en 1 para
apuntar a la siguiente posicin vaca. A la inversa, cuando se ejecuta una
instruccin RETURN, RETLW o RETFIE el contenido de la posicin actual del
stack es colocado en el PC y el apuntador de stack es decrementado en 1.
Nota 1: PCLATH no se modifica en ninguna de estas operaciones
Nota 2: Cuando el apuntador de stack ya est en la posicin 8 y se ejecuta otro
CALL se reinicia a la posicin 1 sobrescribiendo en dicha posicin. No existe
ningn indicador que avise de esta situacin. As que el usuario deber llevar
el control para que esto no ocurra.
2.6.2.- La Memoria de Datos
La memoria de datos consta de dos reas mezcladas y destinadas a funciones
distintas:
Registros de Propsito Especial (SFR)
Registro de Propsito General (GPR)
Los SFR son localidades asociadas especficamente a los diferentes perifricos y
funciones de configuracin del PIC y tienen un nombre especfico asociado con su
funcin. Mientras que los GPR son memoria RAM de uso general.

16

Descripcin General del PIC16F877


Bancos de memoria
Toda la memoria de datos est organizada en 4 bancos numerados 0, 1, 2 y 3.
Para seleccionar un banco se debe hacer uso de los bits del
registro
STATUS<7:5> denominados IRP, RP1 y RP0.
Hay dos maneras de acceder a la memoria de datos: Direccionamiento directo e
indirecto. La seleccin de bancos se basa en la siguiente tabla
Direcc. Indirecto (IRP)

RP1:RP0
00
01
10
11

0
1

Banco
0
1
2
3

Cada banco consta de 128 bytes (de 00h a 7Fh). En las posiciones ms bajas de
cada banco se encuentran los SFR, y arriba de stos se encuentran los GPR.
Toda la memoria de datos est implementada en Ram esttica.
Direccionamiento Directo
Para acceder una posicin de memoria mediante direccionamiento directo, la CPU
simplemente usa la direccin indicada en los 7 bits menos significativos del cdigo
de operacin y la seleccin de banco de los bits RP1:RP0 como se ilustra en la
siguiente figura.

17

Descripcin General del PIC16F877


Direccionamiento indirecto
Este modo de direccionamiento permite acceder una localidad de memoria de
datos usando una direccin de memoria variable a diferencia del direccionamiento
directo, en que la direccin es fija. Esto puede ser til para el manejo de tablas de
datos.
El registro INDF.- En la figura anterior se muestra la manera en que esto se
realiza. Para hacer posible el direccionamiento indirecto se debe usar el registro
INDF. Cualquier instruccin que haga un acceso al registro INDF en realidad
accesa a la direccin apuntada por el registro FSR (File Select Register).
La seleccin de banco en el caso de direccionamiento indirecto se realiza
mediante los bits IRP (STATUS<7>) y el bit 7 del registro FSR, como se muestra
en la figura.
El registro INDF mismo al leerse de manera indirecta (con FSR=0) producir un
cero. Y al escribirse de manera indirecta no es afectado.
A continuacin se muestra un ejemplo del uso de este direccionamiento para
limpiar las localidades RAM 20h a 2Fh.
Ejemplo 3.- Blanqueo de un bloque de memoria de datos desde la localidad 20h a la localidad
2Fh
CLRF STATUS ;Selecciona Banco cero
MOVLW 0X20 ;carga valor de apuntador a RAM
MOVWF FSR
;inicializa apuntador
Sigue
CLRF INDF
;limpia localidad apuntada por FSR
INCF FSR,F ;incrementa apuntador
BTFSS FSR,4 ;si ya termin escapa a continuar
GOTO sigue ;si no repite
Contina
...

En el siguiente ejemplo se muestra la manera como se switchea mediante


instrucciones dentro del programa de un banco a otro
Ejemplo 4.- Switcheo entre bancos de memoria RAM
CLRF STATUS

BSF STATUS,5

BSF STATUS,6

BCF STATUS,5

;Limpia registro STATUS (Banco 0)


;RP0=1, (Banco 1)
;RP1=1, (Banco 3)
;RP0=0, (Banco 2)

El Archivo de Registros
Aunque el archivo de registros en RAM puede variar de un PIC a otro, la familia
del PIC16F87x coincide casi en su totalidad. En la siguiente figura se muestra a
18

Descripcin General del PIC16F877


detalle el mapa de este archivo de registros y su organizacin en los cuatro
bancos que ya se describieron.
Direccin
00h
01h
02h
03h
04h
05h
06h
07h
08h
09h
0Ah
0Bh
0Ch
0Dh
0Eh
0Fh
10h
11h
12h
13h
14h
15h
16h
17h
18h
19h
1Ah
1Bh
1Ch
1Dh
1Eh
1Fh
20h

registro
INDF(*)
TMR0
PCL
STATUS
FSR
PORTA
PORTB
PORTC
PORTD(1)
PORTE(1)
PCLATH
INTCON
PIR1
PIR2
TMR1L
TMR1H
T1CON
TMR2
T2CON
SSPBUF
SSPCON
CCPR1L
CCPR1H
CCP1CON
RCSTA
TXREG
RCREG
CCPR2L
CCPR2H
CCP2CON
ADRESH
ADCON0

Direccin
registro
Direccin
registro
Direccin
registro
80h
INDF(*)
100h
INDF(*)
180h
INDF(*)
81h OPTION_REG
101h
TMR0
181h OPTION_REG
82h
PCL
102h
PCL
182h
PCL
83h
STATUS
103h STATUS
183h
STATUS
84h
FSR
104h
FSR
184h
FSR
85h
TRISA
105h
185h
86h
TRISB
106h
PORTB
186h
TRISB
87h
TRISC
107h
187h
88h
TRISD(1)
108h
188h
89h
TRISE(1)
109h
189h
8Ah
PCLATH
10Ah PCLATH
18Ah
PCLATH
8Bh
INTCON
10Bh
INTCON
18Bh
INTCON
8Ch
PIE1
10Ch EEDATA
18Ch
EECON1
8Dh
PIE2
10Dh
EEADR
18Dh
EECON2
8Eh
PCON
10Eh EEDATH
18Eh RESERVADO(2)
8Fh
10Fh EEADRH
18Fh RESERVADO(2)
90h
110h
190h
91h
SSPCON2
111h
191h
92h
PR2
112h
192h
93h
SSPADD
113h
193h
94h
SSPSTAT
114h
194h
95h
115h
195h
Registros
96h
116h
196h
Registros de
de
97h
117h
197h
propsito
propsito
general (16
98h
TXSTA
118h
198h
general (16
bytes)
99h
SPBRG
119h
199h
bytes)
9Ah
11Ah
19Ah
9Bh
11Bh
19Bh
9Ch
11Ch
19Ch
9Dh
11Dh
19Dh
9Eh
ADRESL
11Eh
19Eh
9Fh
ADCON1
11Fh
19Fh
A0h
120h
1A0h
Registros
Registros de
Registros de
de
Registros de
propsito
propsito
propsito
propsito
General
General
General
General
(80 bytes)
(80 bytes)
(80 bytes)
(96 bytes)
EFh
16Fh
1EFh
Acceso a
Acceso a regs
Acceso a regs
F0h
170h regs 70h
1F0h
70h7Fh
70h7Fh
7Fh
7Fh
FFh
17Fh
1FFh
Banco 0
Banco 1
Banco 2
Banco 3

Notas: (1): Estos registros no estn implementados en el PIC16F876


(2): Estos registros estn reservados, mantngalos limpios
(*) no es un registro fsico
Localidades de memoria de datos no implementadas, se leen como 0

Cada uno de los registros de propsito especial, est asociado a un dispositivo


interno del cc. En el siguiente captulo se tratar con detalle el uso de cada uno
de estos dispositivos y de los registros asociados a l.

19

Descripcin Detallada del PIC16F87

33..-- D
Deessccrriip
pcciin
nD
Deettaallllaad
daa d
deell PPIIC
C1166FF887777
3.1.- Los Puertos Paralelos de Entrada / Salida
Los integrados PIC16F874 y PIC16F877 poseen 5 puertos de entrada / salida
denominados PORTA, PORTB,...,PORTE, mientras que el PIC16F873 y PIC16F876.
Estos puertos son totalmente programables, es decir, sus lneas pueden ser
configuradas para trabajar como entradas o como salidas a seleccin del programador.
3.1.1.- El Puerto A (PORTA).
El puerto A posee 6 lneas bidireccionales. Los 3 registros asociados a este puerto son:
Registro PORTA (05H).- Registro de estado del Puerto A. Cada uno de los 6 bits
menos significativos (RA5,...,RA0) de este registro estn asociados a la lnea fsica
correspondiente del puerto. Al hacer una lectura este registro se lee el estado de todas
las patitas del puerto. Todas las escrituras al registro son operaciones del tipo leemodifica-escribe, es decir, toda escritura al puerto implica que el estado de las patitas
es ledo, luego es modificado y posteriormente se escribe al latch de datos del puerto.
POR, BOR
otros Reset

0
0

x
u

0
0

0
0

0
0

0
0

05h

RA5

RA4

RA3

RA2

RA1

RA0

Bit

Registro PORTA (05h)


Registro TRISA (85H).- Cada bit de este registro configura la direccin en que fluye la
informacin de la patita correspondiente del puerto A, as, para k=0,1,...,5:}
Bit k de TRISA = 1 configura la patita RAk del puerto A como Entrada
Bit k de TRISA = 0 configura la patita RAk del puerto A como Salida
POR, BOR
otros Reset

85h

Bit

1
1

1
1

1
1

1
1

1
1

1
1

Registro de direccin de datos del puerto A


5

Registro TRISA (85h)


Todas las patitas del puerto A poseen diodos de proteccin conectados a Vdd (contra
altos voltajes de entrada) y a Vss (contra voltajes negativos) adems, manejan niveles
de entrada tipo TTL y como salidas se comportan como drivers tipo CMOS. Excepto la
patita RA4, la cual como entrada posee un Disparador Schmitt y como salida es de
Drenaje abierto, adems RA4 slo posee un diodo de proteccin conectado a Vss.
El Registro ADCON1 (9FH).- Las patitas RA0, RA1, RA2, RA3 y RA5 estn
multiplexadas con las entradas analgicas AN0,...,AN4, de manera que antes de
utilizarlas debemos configurar si sern usadas como entradas analgicas o como
entradas / salidas digitales. Para seleccionar la segunda opcin (entradas / salidas
digitales) se debe colocar en la mitad menos significativa de este registro un 01102 (es
decir, un 06h).
1

Descripcin Detallada del PIC16F87


En las siguientes dos figuras se muestra el detalle de implementacin interna de las
patitas del puerto A, mostrando la diferencia entre las patitas RA4 y las dems patitas
del puerto A

Patitas RA0,RA1,RA2,RA3 y RA5

Patita RA4

Ejemplo 1: Salidas digitales.- En este ejemplo se configuran las patitas RA0,...,RA3


del puerto A para manejar el encendido y apagado de 4 diodos luminosos conectados a
ellos.
Include p16f877.inc
org 0x0000
;Inicia en el vector de reset
;Inicializacin del puerto A:
CLRF STATUS
;Selecciona Banco 0
CLRF PORTA
;Inicializa latches de datos de PORTA
BSF
STATUS,RP0 ;Selecciona Banco 1
MOVLW 0x06
;Configura todas las patitas de A
MOVWF ADCON1
;como digitales
MOVLW 0x00
;configura todas patitas de A
MOVWF TRISA
;como salidas digitales
;Una vez inicializado el puerto, se procede a controlar los LEDs
BCF STATUS,RP0
;regresa al banco 0
ciclo CLRF PORTA
;Apaga todos los LEDs
BSF PORTA,0
;enciende el LED RA0
BSF PORTA,1
;enciende el LED RA1
BSF PORTA,2
;enciende el LED RA2
BSF PORTA,3
;enciende el LED RA3
GOTO ciclo
end

Hardware necesario.- Como prcticamente en todos los programas para PIC, si no


conectamos el hardware adecuado no podremos ver ningn efecto al ejecutar el
programa. En este caso, el hardware es muy simple, adems de conectar las seales
2

Descripcin Detallada del PIC16F87


de reloj de acuerdo a alguna de las opciones descritas en el captulo anterior y consiste
en 4 LEDs conectados a las patitas RA0,...,RA3 con las respectivas resistencias
limitadoras de corriente, como se muestra en la siguiente figura:
RA0
RA1

PIC

RA2
RA3
RA4
RA5

Observacin. Al ejecutar el programa en un PIC real con un cristal de 4 Mhz (no


simulado) a simple vista no podemos apreciar el parpadeo de los LEDs, ya que
stos se encienden durante tres a seis seg y se apagan durante 1 a 3 seg.

Ejemplo 2: Entradas digitales.- En este segundo ejemplo se configura la patita RA5


del puerto A como salida conectada a un LED, el cual se controla de acuerdo al estado
de las patitas RA0 y RA1 configuradas como entradas
;*Este programa Enciende un LED conectado a RA5 cuando se presiona un botn
;*conectado a RA1 y lo apaga cuando se presiona un botn conectado a RA0
;*****************************************************************************
include p16f877.inc
org 0x0000
;Inicia en el vector de reset
;Inicializacin del puerto A:
CLRF STATUS
;Selecciona Banco 0
CLRF PORTA
;Inicializa latches de datos de PORTA
BSF
STATUS,RP0 ;Selecciona Banco 1
MOVLW 0x06
;Configura todas las patitas de A
MOVWF ADCON1
;como digitales
MOVLW 0x1F
;configura todas las patitas de A como entradas
MOVWF TRISA
;y RA5 como salida
;Una vez inicializado el puerto, se procede leer las patitas RA0 y RA1
BCF STATUS,RP0
;regresa al banco 0
chRA0 BTFSS PORTA,0
;checa si RA0=1
GOTO chRA1
;si RA=0 salta a checar RA1
Apaga BCF PORTA,5
;si RA0=1 apaga el LED
chRA1 BTFSS PORTA,1
;checa si RA1=1
GOTO chRA0
;si RA1=0 salta a checar RA0
Prend BSF PORTA,5
;si RA1=1 enciende el LED
GOTO chRA0
end

Hardware necesario.- En la siguiente figura se muestra la conexin de los dos botones


y el LED necesarios para probar el programa, adems claro est de la circuitera de
reloj necesaria.

Descripcin Detallada del PIC16F87


+V
Apaga
RA0
RA1

PIC

Enciende

RA2

+V

RA3
RA4
RA5

El efecto rebote y su eliminacin


En el momento de presionar un botn pulsador o cualquier conmutador electromecnico
es inevitable que se produzca un pequeo arco elctrico durante el breve instante en
que las placas del contacto se aproximan o se alejan de sus puntos de conexin, ya
que las distancias microscpicas entre los puntos a diferente potencial son suficientes
para romper por un instante la resistividad del aire. Este fenmeno se conoce como
rebote (bounce) y se ilustra en la siguiente figura
+5

V1

Circuito

V2

Lgico
V1

V2

Se suelta el botn

Se suelta el botn

Se presiona el botn

Se presiona el botn

Duracin del rebote.- La experiencia emprica indica que el periodo transitorio de un


rebote depende entre otros factores, de la calidad de los switches y de la rapidez de su
accionamiento, pero a lo ms puede durar unos 20 milisegundos, En la siguiente
figura se muestra un rebote real en los contactos de un relevador capturado en la
pantalla de un osciloscopio digital Fluke 123. (Obsrvese que el rebote mostrado dur
solamente 3 milisegundos).

Descripcin Detallada del PIC16F87

Ejemplo 3: Limpiado del rebote (debouncing).- El rebote generado por un switch no


siempre es un problema, por ejemplo el programa del ejemplo anterior funciona
correctamente haya o no haya rebote. Sin embargo, qu pasara si se desea controlar
el encendido y apagado del LED con un solo botn? En este caso s se debe
contemplar el limpiado del rebote. (Siempre que a una sola tecla le asignemos dos o
ms funciones diferentes en un programa debemos considerar el efecto del rebote).
En este ejemplo se usa slo el botn conectado a la patita RA0 para controlar el
encendido y apagado del LED, y se incluye el limpiado del rebote.
;*Este programa Enciende un LED conectado a RA5 cuando se presiona un botn
;*conectado a RA0 y lo apaga cuando se presiona presiona nuevamente el
;*mismo botn y a s sucesivamente.
;**************************************************************************
include p16f877.inc
org 0x0000
;Inicia en el vector de reset
;Inicializacin del puerto A:
CLRF STATUS
;Selecciona Banco 0
CLRF PORTA
;Inicializa latches de datos de PORTA
BSF
STATUS,RP0 ;Selecciona Banco 1
MOVLW 0x06
;Configura todas las patitas de A
MOVWF ADCON1
;como digitales
MOVLW 0x1F
;configura todas las patitas de A como salidas
MOVWF TRISA
;y RA5 como salida
BCF STATUS,RP0
;regresa al banco 0
checa BTFSS PORTA,0
;checa si RA0=1
GOTO checa
;si RA=0 checa de nuevo
CALL d20ms
;si RA0=1 espera 20 miliseg. A que pase el rebote
chec1 BTFSS PORTA,0
;checa nuevamente si RA0=1
GOTO checa
;si RA1=0 falsa alarma, vuelve a checar
MOVLWF PORTA,0x20 ;si RA1=1 seal vlida; carga mscara en W
XORWF PORTA,1
;conmuta estado del LED
GOTO checa
;repite
end

Hardware necesario.- El hardware es igual al del ejemplo 2, pero usando slo el botn
conectado a RA0.

Descripcin Detallada del PIC16F87


Ejemplo 4. Pausa de 20 milisegundos.- En el cdigo anterior se resalta la parte
correspondiente al limpiado del rebote, la cual incluye un subrutina (d20ms) que no se
muestra en el recuadro, esta rutina simplemente realiza una pausa de 20 milisegundos.
A continuacin se muestran dos diferentes implementaciones de esta rutina
(suponiendo un reloj de 100 Khz):
;* Rutina de Pausa que dura 20 milisegundos (usando memoria de datos)
;* (Supone un reloj de 100 Khz)
;**************************************************************************
;Define constantes
N
EQU 0xA5
cont EQU 0x20
; inicia rutina
d20ms MOVLW N
;Carga dato que controla la duracin
MOVWF cont
;inicializa contador con el dato
rep
DECFSZ cont,1
;Decrementa contador y escapa si cero
GOTO rep
;si no es cero, repite
esc
RETURN
;regresa de esta subrutina
end
;* Rutina de Pausa que dura 20 milisegundos (sin usar memoria de datos)
;* (Supone un reloj de 100 Khz)
;**************************************************************************
;Define dato que controla la duracin
N
EQU ???
;inicia rutina
d20ms MOVLW N
;Carga dato que controla la duracin
rep
ADDLW 0xFF
;Le suma 1
BTFSS STATUS,2
;Si es cero escapa
GOTO rep
;si no es cero, repite
esc
RETURN
;regresa de esta subrutina
end

Clculo de N.- Para lograr que la duracin de la subrutina presentada sea de 20


milisegundos es necesario elegir adecuadamente el valor de la constante N. Para ello
ejemplificamos el clculo en la primera de las dos versiones: A continuacin se repite el
cdigo fuente de la rutina incluyendo entre parntesis el nmero de ciclos que dura
cada instruccin:
d20ms MOVLW N
MOVWF cont
rep
DECFSZ cont,1
GOTO rep
esc
RETURN

;(1)
;(1)
;(1 si no escapa, 2 si escapa)
;(2)
;(2)

De manera que el nmero de ciclos de instruccin Tsub consumidos por la rutina,


incluyendo los 2 ciclos de la llamada (CALL) sern
Tsub = [2+1+1+(N-1)*(1+2)+2+2] ciclos
Lo cual se puede expresar en segundos como
Tsub = (3N+5) Tcy

Descripcin Detallada del PIC16F87


Donde Tcy es la duracin en segundos de un ciclo de instruccin. Suponiendo que se
est usando un reloj de 100 Khz, (Tcy=40seg), despejando
N = (Tsub/Tcy 5)/3
Sustituyendo Tsub = 20 mseg; entonces N =165 = A5H.

Observacin. La mxima duracin que se puede lograr con esta rutina (Para N=0 el
ciclo se ejecuta 256 veces) es de 30.92 mseg (con la frecuencia del reloj de 100 Khz
supuesta). As, si la frecuencia del reloj es mayor, por ejemplo, en el modo de
oscilador interno se tienen 4 Mhz y Tcy=1seg esta rutina no podr proporcionar
nunca los 20 mseg y habr que realizar una pausa ms larga anidando dos ciclos.

Ejercicio.- Calcula la duracin en ciclos de instruccin y en segundos para la segunda


versin en trminos de N. Despeja N para Tsub = 20 mseg. Cul es la mxima duracin
de esta rutina? con qu valor de N se logra?
Ejemplo 5. Pausa con dos ciclos anidados.- Como ya se mencion, la pausa del
ejemplo 4 es demasiado corta, de manera que para frecuencias altas de reloj no puede
alcanzar ni siquiera los 20 mseg. A continuacin se muestra una pausa que puede dar
tiempos mucho ms largos usando ciclos anidados:
;* Rutina de Pausa para tiempos largos
;* (Adecuada para un reloj de 4 Mhz)
;**************************************************************************
;Define constantes Para 20 milisegundos
N
EQU 0x1A
M
EQU 0x0
cont1 EQU 0x20
cont2 EQU 0x21
;inicia rutina
pau
MOVLW N
;(1) Carga dato N
MOVWF cont1
;(1) inicializa contador1 ciclo externo
rep1 MOVLW M
;(1) Carga dato M
MOVWF cont2
;(1) inicializa contador2 ciclo interno
rep2 DECFSZ cont2,1
;(1,2)Decrementa contador2 y escapa si cero
GOTO rep2
;(2) si no es cero, repite ciclo interno
DECFSZ cont1,1
;(1,2)Decrementa contador1 y escapa si cero
GOTO rep1
;(2) si no es cero repite ciclo externo
esc
RETURN
;(2) regresa de esta subrutina
end

La duracin de esta rutina en ciclos de reloj ser


Tsub = 2+1+1+N*[1+1+(M-1)*(1+2)+2+1+2]+1-2+2+2 ciclos
Lo cual se puede simplificar como sigue
Tsub = [N*(3M+4)+7] Tcy

Descripcin Detallada del PIC16F87


La mxima duracin de esta rutina se obtiene para N=M=256, lo cual en el programa se
logra con N=M=0; entonces Tsub mximo = 197,639 Tcy. Para una frecuencia de 4 Mhz
Tcy = 1 seg, entonces Tsub mximo =0.197639 seg.
Si deseamos Tsub = 20 mseg, haciendo M=256, despejando N
N = (Tsub/Tcy 7)/(3M+4)
Sustituyendo valores N= 25.89 1Ah. (debido a la aproximacin la rutina realmente
dura 20.08 mseg.

Observacin. Hasta aqu se estn realizando pausas de duracin controlada por


software, sin embargo, lo ms adecuado para controlar tiempo de manera ms
exacta es usar los timers que se vern ms adelante.

3.1.2.- El Puerto B (PORTB)


El puerto B es un puerto digital de 8 bits, todas sus patitas son bidireccionales y trabaja
en forma similar al puerto A. Tiene tres registros asociados: El registro de datos
PORTB, el registro de direccin de los datos TRISB y el registro OPTION_REG.
Registro PORTB (06H, 106H) .- Los ocho bits que contiene reflejan directamente el
estado de las ocho patitas del puerto B RB0,...,RB7.
Registro TRISB (86H, 186H).- En forma similar a TRISA, al poner un 0 en un bit de
TRISB se configura la patita RB correspondiente como salida y al poner un 1 en un bit
de TRISB se configura la patita RB correspondiente como entrada.
Registro OPTION_REG (81H, 181H).- El bit 7 de este registro, denominado RBPU es
usado para conectar/desconectar una resistencia pull-up conectada a cada patita RB.
Poniendo un 0 en este bit todas las resistencias se conectan. Para desconectar las
resistencias pull-up se debe poner este bit en 1, tambin se desconectan
automticamente cuando la patita correspondiente es configurada como salida. Un
Reset desconecta todas las resistencias.
Patitas RB4,...,RB7.- Estas cuatro patitas del puerto B tienen la capacidad de generar
una solicitud de interrupcin a la CPU cuando estn configuradas como entradas. El
estado de estas patitas es comparado con el ltimo estado que tenan durante la ltima
lectura a PORTB, guardado en un latch. Los bits que indican que hay una diferencia
entre estos valores por cada patita estn conectados a una puerta OR cuya salida
activa el bit RBIF del registro INTCON solicitando con esto una interrupcin. Esta
interrupcin es especialmente til para despertar al dispositivo de su estado de SLEEP
cuando alguna de las cuatro lineas es activada, por ejemplo, en respuesta a la presin
de una tecla.
Esta caracterstica de solicitud de interrupcin cuando se detecta un cambio junto con
las resistencias pull-up configurables para estas cuatro patitas, las hacen ideales para
8

Descripcin Detallada del PIC16F87


el manejo de teclados en dispositivos porttiles que requieren dormirse durante largos
ratos para economizar bateras y despertarse cuando una tecla es presionada.
En la siguientes figuras se muestra el alambrado interno de las patitas del puerto B.

Patitas RB0,...RB3

Patitas RB4,...,RB7

Ejemplo 6. Luces secuenciales.- En este ejemplo se realiza el encendido secuencial


de 8 LEDs conectados a RB0,...,RB7, es decir, se enciende RB0 durante un segundo,
luego RB1 y as sucesivamente hasta llegar a RB7 para recomenzar despus con RB0.
(en un segundo dado slo un LED est prendido).
Hardware necesario.- Slo se requieren los ocho LEDs conectados a las patitas
RBP0,...,RBP7, como se muestra en la siguiente figura.
RB0
RB1

PIC

RB2
RB3
RB4
RB5
RB6
RB7

Descripcin Detallada del PIC16F87


;* Este programa Enciende en secuencia (uno a la vez) 8 LEDs conectados
;* a las patitas del puerto B
;**********************************************************************
;
Include p16f877.inc
org 0x0000
;Inicia en el vector de reset
;Inicializacin del puerto B:
CLRF STATUS
;Selecciona Banco 0
CLRF PORTB
;Inicializa latches de datos de PORTB
BSF STATUS,RP0
;Selecciona Banco 1
CLRF TRISB
;Configura todas las patitas de B como salidas
;Una vez inicializado el puerto, se procede a controlar los LEDs
CLRF STATUS,RP0
;regresa al banco 0 y limpia acarreo
CLRF PORTB
;Apaga todos los LEDs
BSF PORTB,0
;enciende el LED RB0
ciclo CALL d1seg
;pausa de un segundo
RLF PORTB,1
;Recorre posicin encendida a la izquierda
GOTO ciclo
;repite
end

Observacin. Si se usa el mdulo ICD (In Circuit Debuger) para probar este
programa se debe tomar en cuenta que este mdulo usa las lneas RB3, RB6 y RB7
del puerto B para comunicacin y programacin del PIC.

Ejemplo 7. Pausa de 1 segundo.- Para realizar la pausa de un segundo que se


requiere para el programa anterior podemos hacer uso de la pausa implementada en el
ejemplo 5 con su mxima duracin Tsub = 0. 197639 seg (con N=M=0). Para ello
implementamos un tercer ciclo externo que repita esta pausa P veces.
;* Subrutina de Pausa de 1 segundo
;**********************************************************************
P
EQU 0x05
cont3 EQU 0x22
d1seg MOVLW P
;(1)carga duracin del ciclo
MOVWF cont3
;(1)inicializa contador3
ciclo CALL pau
;(196868)pausa de 0.197639 seg
DECFSZ cont3,1
;(1,2)Decrementa y escapa si cero
GOTO ciclo
;(2)si no es cero repite
RETURN
;(2)si es cero retorna

La duracin de esta rutina incluyendo la llamada ser


Tsub = 2+1+1+(P)*(197639+1+2)+1-2+2 ciclos
Es decir,
Tsub = 197642*P+5 Tcy
La mxima duracin de esta rutina (para P=256), suponiendo un reloj de 4 Mhz, se
tiene un Tsub mximo = 50.596,357 segundos. Sin embargo, si deseamos un
Tsub=1seg. Obtenemos, despejando

10

Descripcin Detallada del PIC16F87


P = (Tsub 5)/197642 = 5.059628 5
Ejemplo 8.- Conexin de un teclado matricial
Una de las funciones ms comunes de un microcontrolador es la aceptacin de datos
numricos o alfanumricos suministrados por un operador mediante un teclado.
La mayora de los teclados estn organizados en forma matricial como un conjunto de
switches en las intersecciones de varios renglones y columnas conductoras como se
muestra en la siguiente figura que ejemplifica un teclado de tipo telefnico.
Vdd

RB7

RB6

PIC
RB5
RB4
RB3
RB2
RB1

En la figura tambin se ilustra una conexin tpica con tres lneas de salida del puerto B
que controlan las columnas y cuatro lneas de salida del mismo puerto que recogen la
informacin de los renglones.

Observacin. Es recomendable colocar un diodo de proteccin en cada lnea de


salida del puerto para evitar que al activar ms de una columna a la vez se produzca
un corto circuito.

Procedimiento de deteccin de teclas y codificacin.- Para la deteccin y


asignacin de cdigo segn la tecla presionada se procede como sigue:
1. Deteccin. Se ponen en bajo todos los renglones (cuidando que haya diodos de
proteccin) y se leen las columnas .
2. Si hay alguna columna activa se limpia el rebote, si es tecla vlida se pasa al
paso 3, si no es tecla vlida se asigna un cdigo de ninguna tecla presionada.
3. Codificacin. El puerto activa un regln a la vez colocando un cero lgico en la
lnea correspondiente al rengln a activar.
11

Descripcin Detallada del PIC16F87


4. Por cada rengln activo se lee la informacin de columnas y dependiendo del
rengln y la columna activada (en bajo) se asigna el cdigo a la tecla de la
interseccin.
;* Estas subrutinas realizan la inicializacin y deteccin de un teclado
;* tipo telefnico controlando las columnas con las salidas RB1,RB2 y RB3
;* y los renglones con las entradas RB4,RB5,RB6 y RB7
;* con resistencias pull-up internas para evitar resistencias externas.
;*********************************************************************
;Subrutina de inicializacin del puerto B:
initB CLRF STATUS
;Selecciona Banco 0
CLRF PORTB
;Inicializa latches de datos de PORTB
BSF STATUS,RP0
;Selecciona Banco 1
MOVLW 0xF0
;configura RB7,...,RB4 como entradas
MOVWF TRISB
;y RB3,RB2,RB1 como salidas
BCF OPTION_REG,7 ;Conecta todas las resistencias Pull-Up
BCF STATUS,RP0
;regresa al Banco 0
RETURN
;Subrutina de Deteccin de tecla presionada: regresa w=0 si no hay tecla
;presionada y w=0xFF si hay alguna tecla presionada
detec CLRF PORTB,1
;activa las cuatro columnas
BTFSS PORTB,7
;lee rengln 1,2,3
GOTO rebo
;si tecla presionada limpia rebote
BTFSS PORTB,6
;lee rengln 4,5,6
GOTO rebo
;si tecla presionada limpia rebote
BTFSS PORTB,5
;lee rengln 7,8,9
GOTO rebo
;si tecla presionada limpia rebote
BTFSS PORTB,4
;lee rengln *,0,#
GOTO rebo
;si tecla presionada limpia rebote
RETLW 0x0
;no hubo tecla presionada retorna con w=0
rebo CALL d20ms
;pausa de 20 milisegundos
BTFSS PORTB,7
;lee rengln 1,2,3
RETLW 0xFF
;tecla presionada, retorna con w=0xFF
BTFSS PORTB,6
;lee rengln 4,5,6
RETLW 0xFF
;tecla presionada, retorna con w=0xFF
BTFSS PORTB,5
;lee rengln 7,8,9
RETLW 0xFF
;tecla presionada, retorna con w=0xFF
BTFSS PORTB,4
;lee rengln *,0,#
RETLW 0xFF
;tecla presionada, retorna con w=0xFF
RETLW 0x0
;falsa alarma retorna con w=0

A continuacin se presenta la rutina de codificacin que asigna el cdigo ASCII de la


tecla presionada y lo devuelve en el registro W
;* Esta subrutina realiza la codificacin del teclado tipo telefnico
;* retornando en W el cdigo ASCII de la tecla presionada
;* regresa W=0 si no hubo tecla presionada
;*********************************************************************
codif MOVLW 0xF7
;desactiva todas las columnas
MOVWF PORTB
;y activa la columna 1,4,7,*
BTFSS PORTB,7
;Es la tecla 1?
RETLW 1
;retorna cdigo del 1
BTFSS PORTB,6
;Es la tecla 4?
RETLW 4
;retorna cdigo del 4

12

Descripcin Detallada del PIC16F87


BTFSS
RETLW
BTFSS
RETLW
MOVLW
MOVWF
BTFSS
RETLW
BTFSS
RETLW
BTFSS
RETLW
BTFSS
RETLW
MOVLW
MOVWF
BTFSS
RETLW
BTFSS
RETLW
BTFSS
RETLW
BTFSS
RETLW
RETLW

PORTB,5
7
PORTB,4
*
0xFB
PORTB
PORTB,7
2
PORTB,6
5
PORTB,5
8
PORTB,4
0
0xFD
PORTB
PORTB,7
3
PORTB,6
6
PORTB,5
9
PORTB,4
#
0x00

;Es la tecla 7?
;retorna cdigo del 7
;Es la tecla *?
;Retorna cdigo del *
;desactiva todas las columnas
;y activa la columna 2,5,8,0
;Es la tecla 2?
;retorna cdigo del 2
;Es la tecla 5?
;retorna cdigo del 5
;Es la tecla 8?
;retorna cdigo del 8
;Es la tecla 0?
;Retorna cdigo del 0
;desactiva todas las columnas
;y activa la columna 3,6,9,#
;Es la tecla 3?
;retorna cdigo del 3
;Es la tecla 6?
;retorna cdigo del 6
;Es la tecla 9?
;retorna cdigo del 9
;Es la tecla #?
;Retorna cdigo del #
;falsa alarma, no hay tecla presionada

O Observacin: La repeticin de cdigo se puede evitar utilizando direccionamiento


indirecto dentro de un ciclo, sin embargo, esto slo representa un ahorro de cdigo y
de memoria para teclados de mayor complejidad.

3.1.3.- El puerto C (PORTC).


El puerto C consta de 8 lneas bidireccionales. Trabaja en forma similar a los dos
puertos anteriores y tiene asociados los registros:
Registro PORTC (07H).- Es el registro de datos cuyos 8 bits RC7,RC6,...,RC0 reflejan
directamente el valor lgico de las lneas fsicas del puerto C.
Registro TRISC(87H).- Registro de control de direccin de las lneas del puerto C.
Poniendo un 1 en un bit del registro TRISC se configura la lnea correspondiente como
entrada y poniendo un 0 se configura la lnea correspondiente como salida.
Las lneas del puerto C se encuentran multiplexadas con varias lineas controladas por
otros perifricos, cuando se habilita la lnea del perifrico respectivo puede ser ignorada
la configuracin de TRISC, de hecho, algunos perifricos configuran la lnea como
salida mientras que otros la configuran como entrada.
Cada entrada del puerto C posee un buffer con disparador Schmitt. Adems, cuando se
selecciona la funcin I2C, las patitas PORTC<4,3> pueden ser configuradas con niveles
I2C o con niveles SMBus mediante el bit CKE del registro SSPSTAT<6>, como se
muestra en las figuras siguientes.
13

Descripcin Detallada del PIC16F87

Patitas 7,6,5,2,1 y 0 del puerto C


Patitas 4 y 3 del puerto C

En la siguiente tabla se resumen las lneas del puerto C y las de los perifricos que
estn multiplexadas con ellas.

Nombre
Funcin multiplexada
RC0/T1OSO/T1CKI Salida oscilatoria del Timer1/reloj de entrada del Timer 1
RC1/T1OSI/CCP2 Entrada oscilatoria del Timer1/entrada de captura2 o salida de
comparacin2 o salida PWM2
RC2/CCP1
Entrada de captura1 o salida de comparacin1 o salida PWM1
RC3/SCK/SCL
Reloj para los modos de comunicacin serie sncrona SPI e I2C
RC4/SDI/SDA
Dato de entrada (en modo SPI)/ Dato de entrada-salida (modo I2C)
RC5/SDO
Dato de salida (en modo SPI)
RC6/TX/CK
Linea de transmisin asncrona de la USART/reloj sncrono
RC7/RX/DT
Linea de recepcin asncrona de la USART/dato sncrono

Ejemplo 9.- Manejo de un Display de 7 segmentos


Un display de siete segmentos es un arreglo de 7 LEDs conectados como se muestra
en la siguiente figura:

14

Descripcin Detallada del PIC16F87


a
f

a b c d e f
g ctodo
comn

d
arreglo de
segmentos
siete

a b c d e f
g nodo
comn

Para este ejemplo se supone un display de nodo comn conectado al puerto C como
se muestra a continuacin

RC1

RC2

PIC

Vdd

RC0

RC3

RC4

RC5

RC6

Inc
RC7

El programa visualiza dgitos numricos hexadecimales en el display, de acuerdo a la


codificacin mostrada en la siguiente tabla
Dato
0
1
2
3
4
5
6
7
8
9

a b c d e

Cdigo

0
1
0
0
1
0
0
0
0
0

0
1
1
1
0
0
1
1
0
0

1
1
0
0
0
0
1
1
0
0

01
4F
12
06
4C
24
3F
0F
00
04

0
0
0
0
0
1
1
0
0
0

0
0
1
0
0
0
1
0
0
0

0
1
0
0
1
0
1
1
0
0

0
1
0
1
1
1
1
1
0
1

Dato
A
b
C
d
E
F

Cdigo

0
1
0
1
0
0

0
1
1
0
1
1

0
0
1
0
1
1

1
0
0
0
0
1

0
0
0
0
0
0

0
0
0
1
0
0

0
0
1
0
0
0

08
60
31
42
30
38

;* Este programa despliega un dgito hexadecimal en un display de nodo


;* comn conectado al puerto C. El dgito se incrementa en 1 cada vez que
;* se presiona un botn conectado al MSB del mismo puerto C

15

Descripcin Detallada del PIC16F87


;************************************************************************
Include p16f877.inc
cont equ 0x20
org 0x0000
inic BSF STATUS,RP0
;banco 1
MOVLW 0x80
;Todos los bits del puerto C como salidas
MOVWF TRISC
;y el MSB como entrada
BCF STATUS,RP0
;regresa al Banco 0
MOVLW 0x01
;
MOVWF PORTC
;Despliega un cero
CLRF cont
;Inicializa contador en cero
tecla BTFSS PORTC,7
;checa botn
GOTO tecla
;Si no se ha presionado espera
CALL d20ms
;pausa de 20 milisegundos
BTFSS PORTC,7
;checa nuevamente el botn
GOTO tecla
;tecla falsa, espera de nuevo
INCF cont,1
;tecla vlida, incrementa contador
CALL codigo
;obtiene cdigo para desplegar el contador
MOVWF PORTC
;despliega contador
suelt BTFSC PORTC,7
;checa de nuevo el botn
GOTO suelt
;si sigue presionado espera
GOTO tecla
;si ya se solt espera nueva presin.
codigo:
MOVLW 0x0F
;carga mscara
ANDWF cont,0
;enmascara el contador y lo deja en W
ADDWF PCL,1
;Salta W instrucciones adelante
RETLW 0x01 ;cdigo del 0
RETLW 0x4F ;cdigo del 1
RETLW 0x12 ;cdigo del 2
RETLW 0x06 ;cdigo del 3
RETLW 0x4C ;cdigo del 4
RETLW 0x24 ;cdigo del 5
RETLW 0x3F ;cdigo del 6
RETLW 0x0F ;cdigo del 7
RETLW 0x00 ;cdigo del 8
RETLW 0x04 ;cdigo del 9
RETLW 0x08 ;cdigo de la A
RETLW 0x60 ;cdigo de la b

RETLW 0x38 ;cdigo de la F


end

Observacin: Una manera ms cmoda de escribir la lista de instrucciones RETLW al


final del programa anterior puede lograrse usando la directiva DT (Define Table) del
ensamblador, la cual nos permite definir una tabla de datos que ser sustituida por una
lista de instrucciones RETLW; as, la lista anterior puede quedar como sigue:
DT 0x01,0x4F,0x12,0x06,0x4C,0x24,0x3F,0x0F
DT 0x00,0x04,0x08,0x60,0x31,0x42,0x30,0x38

3.1.4.- Los Puertos D y E


Estos dos puertos no se encuentran disponibles en los circuitos PIC16F873 y
PIC16F876.

16

Descripcin Detallada del PIC16F87


El puerto D es un puerto de 8 lneas configurables como entradas o salidas mediante el
registro TRISD (88H) y cuyas lneas pueden ser accesadas mediante el registro PORTD
(08H). Cuando se configuran como entradas stas poseen un disparador Schmitt.
El Puerto E slo posee 3 lneas configurables como entradas o salidas mediante el los
3 bits menos significativos del registro TRISE (89H). Sus lneas pueden ser accesadas
mediante los 3 bits menos significativos del registro PORTE (09H). Las lneas del puerto
E estn compartidas con el convertidor analgico / digital, por ello, antes de usarlas
debern ser configuradas como entradas / salidas digitales o analgicas, segn se
desee en forma similar a como se hizo con el puerto A, usando el registro de
configuracin ADCON1 (9FH).
El Puerto D puede configurarse para trabajar simultneamente con sus 8 bits como un
puerto esclavo (Parallel Slave Port) de comunicacin paralela bidireccional con lneas
de protocolo proporcionadas por las tres lneas del Puerto E, para ello se deber activar
el bit PSPMODE (TRISE<4>).

33..22..-- EEll PPuueerrttoo SSeerriiee U


T
RT
AR
USSA
3.2.1.- Introduccin
La USART (Universal Synchronous Asynchronous Receiver Transmitter) es uno de los
dos perifricos contenidos en el PIC que le permiten realizar comunicacin en serie. El
otro es el MSSP (Master Synchronous Serial Port), el cual no es tratado en estas notas.
La USART, tambin conocida como SCI (Serial Communications Interface) puede
configurarse como una unidad de comunicacin en serie para la transmisin de datos
asncrona con dispositivos tales como terminales de computadora o computadoras
personales, o bien para comunicacin sncrona con dispositivos tales como
convertidores A/D o D/A, circuitos integrados o memorias EEPROM con comunicacin
serie, etc.
La gran mayora de los sistemas de comunicacin de datos digitales actuales utilizan la
comunicacin en serie, debido a las grandes ventajas que representa esta manera de
comunicar los datos:

Econmica.- Utiliza pocas lneas de transmisin inclusive puede usar slo una
lnea.
Confiable.- Los estndares actuales permiten transmitir datos con bits de paridad y
a niveles de voltaje o corriente que los hacen poco sensibles a ruido externo.
Adems por tratarse de informacin digital, los cambios en amplitud de la seales
(normalmente causados por ruido) afectan muy poco o nada a la informacin.
Verstil.- No est limitada a usar conductores elctricos como medio de
transmisin, pudiendo usarse tambin: fibra ptica, aire, vaco, etc. Adems el tipo
de energa utilizada puede ser diferente: luz visible, infrarroja, ultrasonido, pulsos
elctricos, radio frecuencia, microondas, etc.

17

Descripcin Detallada del PIC16F87


Una gran cantidad de perifricos se comunican actualmente en serie con una micro
computadora: lneas telefnicas, terminales remotas, unidades de cassette magntico,
el ratn, teclados, etc.
Comunicacin en paralelo.- En este caso se utiliza una lnea fsica por cada bit del
dato a comunicar adems de posibles lneas para protocolo. Esquemticamente en la
siguiente figura se muestra como se transmitira el dato de 8 bits 1001 0111= 97h.
Este tipo de comunicacin se puede realizar mediante el PIC usando el puerto D como
puerto de datos y las lneas del puerto E como lneas de protocolo.

Transmisor

1
0
0
1
0
1
1
1

Receptor

La principal ventaja de la comunicacin paralelo es la alta velocidad de transmisin, ya


que se envan simultneamente todos los bits de un dato. No obstante, si la distancia
entre el transmisor y el receptor es grande, puede ser que el costo de las lneas sea tan
alto que se vuelva incosteable este mtodo de comunicacin.
Comunicacin en Serie: En cambio, la comunicacin en serie slo utiliza una lnea
para la transmisin de datos, y opcionalmente alguna lnea o lneas para protocolo. Por
ejemplo, en la siguiente figura se muestra como se transmitira en serie el mismo dato
(97h):

10010111
Transmisor

Receptor

La desventaja obvia de la comunicacin serie es que los bits de un dato se envan de a


uno por uno, de manera que mientras que la comunicacin en paralelo enva en un ciclo
un dato de 8 bits, a la comunicacin serie le toma ms de 8 ciclos (ya que adems del
dato en la comunicacin serie se requiere agregar algunos bits de sincronizacin.
Sin embargo, debido a que la comunicacin serie requiere slo una lnea para la
transmisin esto abarata los costos en lneas de transmisin y no slo esto, ya que este
hecho tambin hace posible que los datos puedan ser enviados no necesariamente por
un conductor elctrico, sino inclusive por aire o por el vaco si en lugar de pulsos
elctricos se usan impulsos electromagnticos, tales como: ondas de radio, microondas,
pulsos luminosos, infrarrojo, ultrasonido, lser (a travs de fibra ptica), etc.

18

Descripcin Detallada del PIC16F87


3.2.2.- Protocolo de comunicacin serie.
A diferencia de la comunicacin en paralelo, en la comunicacin en serie se hace
necesario establecer mtodos de sincronizacin para evitar la interpretacin errnea de
los datos transmitidos. Para ilustrar esto consideremos la siguiente informacin en serie:
...0100110001001100100...
Esta informacin puede interpretarse de diversas maneras, (an si se recibe a la
velocidad adecuada) dependiendo del punto de inicio de separacin de datos, por
ejemplo, una posible interpretacin sera como sigue:
... 01 00110001 00110010 0 ...
Que interpretado como cdigos ASCII corresponde a los caracteres 1 y 2. Sin
embargo, otra posible interpretacin es:
... 010 01100010 01100100
Que corresponde a los caracteres b y d .
Sincronizacin de bit.- Una manera de resolver el problema anterior es la
sincronizacin de bits que puede realizarse por varios mtodos:
1) Enviar por una lnea adicional una seal de reloj que indique el centro de las
celdas de bits en la lnea de datos (datos no - auto reloj).
2) Enviar con cada bit y por la misma lnea de datos informacin que permita
extraer la seal de reloj (datos auto reloj).
3) Lograr mediante alguna estrategia que los relojes de transmisin y de recepcin
se mantengan en fase continuamente.
Codificacin no auto reloj.- En la figura siguiente se muestran las tres codificaciones
de una lnea de datos:
RZ.- Una celda de bit es 1 si contiene un impulso positivo y un 0 si no lo contiene.
NRZ.- La celda contiene un 1 o 0 de acuerdo al nivel de la seal (constante) en la
celda.
NRZI.- La celda de bit contiene un 1 si hay una transicin y un 0 si no la hay.

RZ

NRZ

NRZI

19

Descripcin Detallada del PIC16F87


Como puede verse, en estos sistemas (RZ, NRZ y NRZI) las secuencias de ceros no
contienen ninguna transicin que permita ubicar la situacin de las celdas de bit. De
hecho, el formato NRZ no la contiene ni en los unos.
Codificacin auto reloj.- Algunos mtodos que contienen en la misma lnea de datos
informacin adicional para determinar la velocidad del reloj a costa de disminuir la
cantidad de informacin til a la mitad que los mtodos no-auto reloj. En la siguiente
figura se muestran los ms utilizados, como son:
PE.- Codificacin de fase.
FSC.- Codificacin por cambio de frecuencia
FM.- Modulacin de frecuencia.
MFM y M2FM.- Modulacin de frecuencia modificadas.

PE
FSC

F M

M FM

M 2F M

Los mtodos autoreloj son muy tiles cuando la velocidad de transmisin no es


constante, por ejemplo, cuando los datos han sido grabados en un medio magntico
giratorio, por ejemplo discos, cintas magnticas, etc.
Sincronizacin de caracter.- Algunos sistemas utilizan lneas adicionales que envan
impulsos para indicar el inicio de un bloque de caracteres. Otros sistemas que no
requieren lneas adicionales a la lnea de datos son:
Mtodo Asncrono.- Cada carcter va sealizado mediante dos bits: un bit de inicio y
un bit de paro, estos dos bits permiten al receptor reconocer el inicio y el final de cada
carcter. La especificacin RS404 de EIA (Electronic Industries Association) define las
caractersticas del mtodo asncrono para transmisin en serie de acuerdo a las
siguientes reglas:
1) Cuando no se envan datos la lnea debe mantenerse en estado 1.
2) Cuando se va a mandar un carcter se enva primero un bit de inicio de valor 0.
3) A continuacin se envan todos los bits del carcter a transmitir al ritmo marcado
por el reloj de transmisin.
4) Despus del ltimo bit del carcter enviado se enva un bit de paro de valor 1.
Mtodo Sncrono.- Cada mensaje o bloque de transmisin va precedido de unos
caracteres de sincronismo. As, cuando el receptor identifica una configuracin de bits
20

Descripcin Detallada del PIC16F87


igual a la de los caracteres de sincronismo da por detectado el inicio y el tamao de los
datos.
Observacin: Para el usuario de un microcontrolador que posee una USART o sistema
similar la manera detallada como el sistema logra establecer la comunicacin resulta
transparente a l, ya que slo tiene que configurar el protocolo del transmisor y del
receptor para que estos logren la comunicacin adecuada, es decir, el usuario
usualmente slo debe configurar:
tipo de comunicacin (sncrona o asncrona)
velocidad de transmisin en Baudios (bits por segundo)
longitud de los datos
bits de inicio y de paro, bits de paridad, etc.

3.2.3.- La USART del PIC16F877


La USART del PIC puede ser configurada para operar en tres modos:
Modo Asncrono (full duplex (transmisin y recepcin simultneas)),
Modo Sncrono Maestro (half duplex)
Modo Sncrono Esclavo (half duplex)
En estas notas slo se cubre el modo asncrono.
Modo Asncrono.
En este modo la USART usa un formato estndar NRZ asncrono, el cual para la
sincronizacin usa: 1 bit de inicio (I), 8 o 9 bits de datos y 1 bit de paro (P). Mientras no
se estn transmitiendo datos la USART enva continuamente un bit de marca. El modo
asncrono se selecciona limpiando el bit SYNC del registro TXSTA (98H). El modo
asncrono es deshabilitado durante el modo SLEEP.
Cada dato es transmitido y recibido comenzando por el LSB. El hardware no maneja bit
de Paridad, pero el noveno bit puede ser usado para este fin y manejado por software.

M arca

D0

D1

D2

D3

D4

D5 D6

D7 (D8)

El mdulo Asncrono de la USART consta de 3 mdulos fundamentales:


El circuito de muestreo
El generador de frecuencia de transmisin (Baud Rate)
El transmisor asncrono
El receptor asncrono.

21

Descripcin Detallada del PIC16F87


El circuito de muestreo.- El dato en la patita de recepcin (RC7/RX/DT) es muestreado
tres veces para poder decidir mediante un circuito de mayora, si se trata de un nivel
alto o un nivel bajo.
3.2.3.1.- El Generador de Baud Rate (BRG)
Este generador sirve tanto para el modo sncrono como el asncrono y consiste de un
contador/divisor de frecuencia de 8 bits controlado por el registro SPBRG (99H). De tal
manera que la frecuencia de transmisin se calcula de acuerdo a la siguiente tabla:
SYNC
0 (modo asncrono)
1 (modo sncrono)

BRGH=0 (baja velocidad)


Baud rate=Fosc/(64(X+1))
Baud rate=Fosc/(4(X+1))

BRGH=1 (Alta velocidad)


Baud rate=Fosc/(16(X+1))
-

En esta tabla X=valor de 8 bits en el registro del divisor, SPBRG. El bit BRGH corresponde a TXSTA<2>.

Debido a que el divisor es de 8 bits, no se puede tener cualquier velocidad de


transmisin deseada, ya que X se deber redondear al entero ms cercano. En las dos
tablas anteriores se muestran algunos valores baud estndares, el divisor necesario
(X=SPBRG) bajo diferentes frecuencias Fosc y el error producido en porcentaje
3.2.3.2.- El transmisor asncrono
En la siguiente figura se muestra el diagrama de bloques del transmisor de la USART.
El corazn de este mdulo es el registro de corrimiento (transmit shift register, TSR). La
nica manera de acceder al registro TSR es a travs del registro TXREG (19H).
22

Descripcin Detallada del PIC16F87


Para transmitir un dato, el programa deber ponerlo primero en el registro TXREG. En
cuanto el TSR termina de enviar el dato que tena (en cuanto transmite el bit de paro)
lee el dato contenido en TXREG (si hay alguno) esto ocurre en un ciclo TCY. En cuanto
el dato de TXREG es transferido al TSR el TXREG queda vaco esta condicin es
indicada mediante el bit bandera TXIF (que es el bit 4 del registro PIR1 (0Ch)), el cual
se pone en alto. Este bit NO puede ser limpiado por software, slo dura un instante en
bajo cuando se escribe un nuevo dato a TXREG. Si se escribe un dato seguido de otro
(back to back) a TXREG el primero se transfiere inmediatamente a TSR y el otro tiene
que esperar hasta que el TSR termine de enviar el bit de Stop del primero. Durante esta
espera TXIF permanece en bajo.
Existe otro bit, llamado TRMT (TXSTA<1>), el cual muesta el estado del TSR. TRMT se
pone en alto cuando TSR est vaco, y en bajo cuando TSR est transmitiendo un dato.
Mientras que TXIF puede generar una interrupcin TRMT no lo puede hacer, TRMT
est pensado para ser consultado por poleo (sin usar interrupciones).

Diagrama de bloques del transmisor de la USART

Para habilitar el mdulo de transmisin es necesario poner en alto el bit TXEN


(TXSTA<5>), mientras no se habilite el mdulo, la patita de transmisin (RC6/TX/CK) se
mantiene en alta impedancia. Si TXEN es deshabilitada a la mitad de una transmisin,
est ser abortada y el transmisor ser reseteado.
Si se est usando un noveno bit TX9 (TXSTA<6>), ste deber ser escrito antes de
escribir los 8 bits restantes a TXREG, ya que en cuanto se escribe un dato a este
registro inmediatamente es transferido a TSR (si ste est vaco).
De acuerdo a lo anterior, la inicializacin del mdulo de transmisin consiste en los
siguientes pasos:
1. Inicializar baud rate escribiendo al registro SPBRG el divisor adecuado y
opcionalmente al bit BRGH .
2. Habilitar comunicacin asncrona limpiando el bit SYNC y poniendo el bit SPEN.
3. Si se van a usar interrupciones, poner el bit TXIE (PIE<4>).
4. Poner el bit TX9 si se desea transmitir datos de 9 bits
5. Habilitar transmisin poniendo el bit TXEN, lo cual pondr el bit TXIF.
23

Descripcin Detallada del PIC16F87


6. Colocar el noveno bit del dato en TX9D si se estn usando datos de 9 bits.
7. Cargar el dato al registro TXREG (inicia la transmisin).
Ejemplo 10.- Transmisin asncrona.
El siguiente programa enva de manera asncrona travs de la USART una cadena de
caracteres. Esta cadena puede ser recibida mediante el puerto serie RS232 de una PC
usando un software de comunicacin tal como la hiperterminal de windows y un cable
de comunicacin serie uno a uno (es decir, un cable sin intercambio interno de
lneas).
;* Este programa enva repetidamente una cadena de caracteres a travs
;* del puerto serie asncrono USART, La cadena utiliza como terminador
;* un carcter "$". Se supone un oscilador a cristal Fosc=14.7456 Mhz
;************************************************************************
Include "p16f877.inc"
apun EQU 0x20
dato EQU 0x21
org 0x0000
trans BSF STATUS,RP0
;banco 1
BCF TXSTA,BRGH
;pone bit BRGH=0 (velocidad baja)
MOVLW 0x17
;valor para 9600 Bauds (Fosc=14.7456 Mhz)
MOVWF SPBRG
;configura 9600 Bauds
BCF TXSTA,SYNC
;limpia bit SYNC (modo asncrono)
BSF TXSTA,TXEN
;pone bit TXEN=1 (habilita transmisin)
BCF STATUS,RP0
;regresa al banco 0
BSF RCSTA,SPEN
;pone bit SPEN=1 (habilita puerto serie)
rep
CLRF apun
;inicializa apuntador
cic2 CALL letrero
;obtiene el siguiente carcter apuntado
MOVWF dato
;lo guarda en dato
SUBLW "$"
;Compara con el signo "$"
BTFSC STATUS,Z
;
GOTO rep
;si es, reinicia
CALL envia
;si no es "$" enva el dato
INCF apun,1
;apunta al siguiente carcter
GOTO cic2
;repite
;*************************************************
;Subrutina para enviar un dato por el puerto serie
;*************************************************
envia BSF STATUS,RP0
;banco 1
esp
BTFSS TXSTA,TRMT
;checa si el buffer de transmisin
GOTO esp
;si est ocupado espera
BCF STATUS,RP0
;regresa al banco 0
MOVF dato,W
;rescata dato a enviar
MOVWF TXREG
;lo enva
RETURN
letrero:
MOVF apun,W ;carga apuntador en W
ADDWF PCL,1 ;Salta W instrucciones adelante
DT "HOLA MUNDO 14.756 Mhz",0x0D,0x0A,"$"
end

3.2.3.3.- El receptor asncrono


El mdulo de recepcin es similar al de transmisin, en la siguiente figura se muestran
los bloques que lo constituyen. Una vez que se ha seleccionado el modo asncrono, la
recepcin se habilita poniendo en alto el bit CREN (RCSTA<4>)

24

Descripcin Detallada del PIC16F87


El dato es recibido mediante la lnea RC7/RX/DT, la cual maneja un registro de
corrimiento de alta velocidad (16 veces el Baud rate).
El corazn del receptor es el registro de corrimiento RSR. Este registro no es acesabel
por software, pero, cuando el dato recibido se ha completado (se ha recibido el bit de
Stop) el dato de RSR es transferido automticamente al registro RCREG (1Ah) si ste
est vaco y al mismo tiempo es puesto en alto la bandera de recepcin RCIF
(PIR1<5>). La nica manera de limpiar la bandera RCIF es leyendo el los datos del
registro RCREG. El registro RCREG puede contener hasta dos datos, ya que es un
buffer doble que funciona como un cola de dos posiciones.
Si las dos posiciones del registro RCREG estn llenas (no han sido ledas) y se detecta
el bit de Stop de un tercer dato de recepcin, lo cual ocasiona un transferencia
automtica del dato recibido a RCREG, esto destruir el primer dato recibido y activar
el indicador de sobreescritura OERR (RCSTA<1>). Para evitar esto, se debern leer los
dos datos en RSREG haciendo dos lecturas consecutivas.
La nica manera de limpiar el bit OERR una vez que ha sido activado es reseteando el
mdulo de recepcin (limpiando CREN y volvindolo a poner), si no se limpia OERR se
bloquea la transferencia de datos de RSR a RCREG y no puede haber ms recepcin
de datos.

Si se detecta un bit nivel bajo en la posicin del bit de stop se pone el indicador de error
de encuadre (frame error) FERR RCSTA<2>. Tanto este indicador como el noveno bit
RX9D de los datos estn en una cola de dos posiciones al igual que los datos recibidos,
de manera que al leer RCREG se actualizan FERR y RX9D con nuevos valores, por lo
cual stos bits debern ser ledos antes de leer RCREG para no perder su informacin.
De acuerdo a lo anterior, la inicializacin del mdulo de recepcin es como sigue:
1. Inicializar el baud rate escribiendo al registro SPBRG el divisor adecuado y
opcionalmente al bit BRGH .
2. Habilitar el puerto serie asncrono limpiando el bit SYNC y poniendo el bit SPEN.
3. Si se van a usar interrupciones, poner el bit RCIE (PIE<5>).
25

Descripcin Detallada del PIC16F87


4. Si se desea recepcin de datos de 9 bits se deber poner el bit RX9
(RCSTA<0>).
5. Habilitar la recepcin poniendo el bit CREN (RCSTA<4>)
6. El bit RCIF se pondr cuando la recepcin de un dato se complete y se generar
una interrupcin si RCIE est puesto.
7. Leer el registro RCSTA para obtener el noveno bit (si se estn recibiendo datos
de 9 bits) o para determinar si ha ocurrido un error de recepcin.
8. Leer los 8 bits del dato recibido leyendo el registro RCREG.
9. Si ocurri algn error este se limpia al limpiar el bit CREN, el cual deber volver a
ponerse si se desea continuar la recepcin.
Para ilustrar este procedimiento se presenta a continuacin un ejemplo de transmisin
de datos en modo asncrono a travs de la USART.
Ejemplo 11.- Recepcin asncrona.
El siguiente programa recibe datos de manera asncrona a travs del la USART. Los
datos recibidos son interpretados por el programa como cadenas de caracteres con un
carcter de terminacin retorno de carro <CR> (elegido arbitrariamente) cuyo cdigo
ASCII es un 0Dh.
Los datos pueden ser enviados mediante el puerto serie RS232 de una PC usando un
software de comunicacin tal como la hiperterminal de windows y un cable de
comunicacin serie uno a uno.
El programa recibe la cadena de caracteres y la compara con la palabra clave
enciende (tambin elegida arbitrariamente), de manera que solamente cuando la
cadena recibida coincide con la palabra clave encender un Led conectado a la lnea
RC0 del puerto C. De lo contrario, (cuando reciba cualquier otra cadena) apagar el
LED.

Observacin: En realidad, por el diseo del programa, cuando se reciba alguna


subcadena inicial de la palabra clave enciende (incluyendo la subcadena vaca) el
Led no cambia de estado.

;* Este programa recibe datos a travs del puerto serie asncrono USART
;* La cadena de caracteres recibidos deber terminar con un carcter <CR>
;* Si la cadena recibida es "enciende" se encender un led conectado a RC0
;* si no, se apagar. Se supone un oscilador Fosc=14.7456 Mhz
;************************************************************************
Include "p16f877.inc"
apun EQU 0x20
dato EQU 0x21
org 0x0000
trans BSF STATUS,RP0
;banco 1
BCF TRISC,0
;pone RC0 como salida
BCF TXSTA,BRGH
;pone bit BRGH=0 (velocidad baja)
MOVLW 0x17
;valor para configurar 9600 Bauds
MOVWF SPBRG
;configura 9600 Bauds
BCF TXSTA,SYNC
;limpia bit SYNC (modo asncrono)
BCF STATUS,RP0
;regresa al banco 0
BSF RCSTA,SPEN
;pone bit SPEN=1 (habilita puerto serie)
BSF RCSTA,CREN
;Habilita recepcin
ciclo CLRF apun
;inicializa apuntador

26

Descripcin Detallada del PIC16F87


sig

CALL recibe
;recibe un caracter del puerto serie
MOVLW 0x0D
;carga caracter de fin de cadena
SUBWF dato,W
;compara
BTFSC STATUS,Z
;ya es fin de cadena?
GOTO longi
;si es, checa longitud de cadena recibida
CALL letrero
;si no es, obtiene un caracter a comparar
SUBWF dato,W
;son iguales?
BTFSS STATUS,Z
;
GOTO noes
;si no son iguales sale del ciclo
INCF apun,1
;si son iguales incrementa apuntador
GOTO sig
;repite para el siguiente caracter
longi MOVLW 0x08
;carga longitud de la palabra clave
SUBWF apun,W
;compara con nmero de caracteres iguales
BTFSC STATUS,Z
BSF PORTC,0
;si coincide Enciende Led
GOTO ciclo
;si no reinicia ciclo
noes CALL recibe
;recibe un caracter del puerto serie
MOVLW 0x0D
;carga caracter de fin de cadena
SUBWF dato,W
;compara
BTFSC STATUS,Z
;ya es fin de cadena?
GOTO apaga
;si es, apaga led
GOTO noes
;si no es, repite
apaga BCF PORTC,0
;apaga el Led
GOTO ciclo
;regresa a esperar nueva cadena
;**************************************************
;subrutina de recepcin de un dato del puerto serie
;**************************************************
recibe BTFSS PIR1,RCIF
;checa el buffer de recepcin
GOTO recibe
;si no hay dato listo espera
MOVF RCREG,W
;si hay dato, lo lee
MOVWF dato
;lo almacena en dato
RETURN
letrero:
MOVF apun,W
;carga apuntador en W
ADDWF PCL,1
;Salta W instrucciones adelante
DT "enciende"
end

Ejemplo 12.- Transmisin / Recepcin Simultnea.


El siguiente programa ilustra la capacidad full duplex que posee la USART del PIC que
le permite realizar simultneamente la transmisin y recepcin de datos.
La tarea que realiza el programa es muy simple, solamente hace el eco del carcter
recibido, es decir, conforme recibe un carcter del puerto serie, lo regresa sin cambio
por el mismo puerto. El proceso se detiene cuando el carcter recibido es un <Esc> o
cdigo ASCII 1Bh (elegido arbitrariamente)
;* Este programa recibe un carcter por el puerto serie asncrono USART
;* y lo regresa tal cual por el mismo puerto, hasta recibir un <esc>
;* Se supone un oscilador a cristal Fosc=14.7456 Mhz
;************************************************************************
Include "p16f877.inc"
dato EQU 0x20
org 0x0000
trans BSF STATUS,RP0
;banco 1
BCF TXSTA,BRGH
;pone bit BRGH=0 (velocidad baja)
MOVLW 0x17
;valor para 9600 Bauds (Fosc=14.7456 Mhz)
MOVWF SPBRG
;configura 9600 Bauds
BCF TXSTA,SYNC
;limpia bit SYNC (modo asncrono)
BSF TXSTA,TXEN
;pone bit TXEN=1 (habilita transmisin)

27

Descripcin Detallada del PIC16F87


BCF STATUS,RP0
;regresa al banco 0
BSF RCSTA,SPEN
;pone bit SPEN=1 (habilita puerto serie)
BSF RCSTA,CREN
;Habilita recepcin
rep
CALL recibe
;recibe dato
MOVLW 0x1B
;carga cdigo ASCII de <escape>
SUBWF dato,W
;es igual?
BTFSC STATUS,Z
;
GOTO fin
;si es igual termina
CALL envia
;si n, retransmite el dato
GOTO rep
;repite
fin
GOTO fin
;ciclo infinito
;*************************************************
;Subrutina para enviar un dato por el puerto serie
;*************************************************
envia BSF STATUS,RP0
;banco 1
esp
BTFSS TXSTA,TRMT
;checa si el buffer de transmisin
GOTO esp
;si est ocupado espera
BCF STATUS,RP0
;regresa al banco 0
MOVF dato,W
;rescata dato a enviar
MOVWF TXREG
;lo enva
RETURN
;**************************************************
;subrutina de recepcin de un dato del puerto serie
;**************************************************
recibe BTFSS PIR1,RCIF
;checa el buffer de recepcin
GOTO recibe
;si no hay dato listo espera
MOVF RCREG,W
;si hay dato, lo lee
MOVWF dato
;lo almacena en dato
RETURN
end

28

Descripcin Detallada del PIC16F87


33..33..-- EEll C
Coonnvveerrttiiddoorr A
Annaallggiiccoo // D
Diiggiittaall

3.3.1.- Descripcin General del Mdulo Conversin Analgico Digital (ADC).


Los PIC16F87X poseen un mdulo ADC interno que les permite manejar 5 entradas
analgicas para los dispositivos de 28 pines y 8 para los otros dispositivos. En la
siguiente figura se muestra un diagrama de bloques del mdulo ADC.
CHS2:CHS0

Vin

GO
(Inicia conversin)

ADIF
(fin de conversin)

Convertidor
Analgico / Digital

DONE
(fin de conversin)

1 1 1

RE2/AN7

1 1 0

RE1/AN6

1 0 1

RE0/AN5

1 0 0

RA5/AN4

0 1 1

RA3/AN3/VREF+

0 1 0

RA2/AN2/VREF0 0 1

Vdd

0 0 0

RA1/AN1
RA0/AN0

Vref+

ADRESH:ADRESL

VrefVss
PCFG3:PCFG0

El multiplexor.- El ADC es un convertidor de aproximaciones sucesivas de 10 bits, el


cual puede realizar la conversin de una de las 8 entradas (o canales) analgicas
AN0,...,AN7 multiplexadas por la lgica interna que utiliza como lneas de seleccin del
canal los bits CHS2:CHS0, en donde se coloca el nmero en binario del canal a
convertir.
Voltajes de Referencia.- Todo convertidor ADC requiere voltajes de referencia que
determinan el valor de mnima escala (VREF-) y el de plena escala (VREF+), de manera
que la conversin de un valor de voltaje analgico Vin en el rango de VREF- a VREF+
producir un valor equivalente binario D en el rango de 0 a 2n, Donde n es la resolucin
del convertidor (n = 10).

29

Descripcin Detallada del PIC16F87


Como la relacin entre escalas es lineal, una regla de tres nos da la relacin entre el
voltaje analgico de entrada (Vin) y el valor digital (D) obtenido por el ADC
D

2 n 1

Vi n VREF
VREF+ VREF

Con la eleccin ms comn: VREF+ = VDD = 5v, VREF- = VSS= 0v, y como n=10,
obtenemos:

D=

1023
5 V in

= 204.6V in

De donde se ve que cuando Vin vara en todo su rango, desde 0 hasta 5v, el valor
obtenido D vara tambin en todo su rango, de 0 a 1023.
Si a la inversa, obtenemos un valor D y deseamos saber que voltaje representa, basta
con despejar:
5
V in = ( 1023
)D = (0.004887585533)D

Observacin: Como puede verse, la conversin del dato D al voltaje


correspondiente requiere una multiplicacin por un nmero fraccionario, para lo cual
el PIC no posee instrucciones, si deseamos realizar esta multiplicacin en el PIC
debemos hacer un programa que multiplique nmeros de punto fijo o de punto
flotante.

3.3.2.- El proceso de Conversin Analgico/Digital.


En el siguiente diagrama de tiempo se muestran los eventos que tienen lugar durante el
proceso de una conversin analgico / digital.
De TCY a TAD

TAD

Reloj del
Convertidor
bit9 bit8 bit7
Seleccin
de canal,
reloj,
encendido y
tiempo de
adquisicin

Inicia
conversin

bit6 bit5 bit4 bit3 bit2

Despus de 100 nseg


desconecta capacitor
de adquisicin

Poner bit
GO=1

Termina conversin:
Actualiza ADRESH:ADRESL
Pone bit G O /D O N E =0
Pone bit ADIF =1
Conecta capacitor

De acuerdo a la figura, para echar a andar el convertidor


siguientes pasos:
1) Configurar el mdulo A/D:
30

bit1 bit0

se debern seguir los

Descripcin Detallada del PIC16F87

2)
3)
4)
5)

6)
7)

a. Configurar los pines analgicos y los Voltajes de referencia VREF- y VREF+,


mediante el registro ADCON1 (9Fh) (y los correspondientes bits TRIS
como entradas)
b. Seleccionar el canal de entrada a convertir mediante los bits CHS2:CHS0
del registro ADCON0 (1Fh)
c. Seleccionar el reloj de conversin mediante los bits ADCS1:ADCS2
(ADCON0<7:6>)
d. Energizar el convertidor mediante el bit ADON (ADCON0<0>)
Configurar interrupciones para el convertidor A/D (si se desea), para ello: limpiar
ADIF y poner ADIE, PEIE y GIE.
Esperar mientras transcurre el tiempo de adquisicin (unos 20 seg).
Iniciar la conversin poniendo el bit GO/DONE (ADCON0<2>).
Esperar a que termine la conversin:
a. Por poleo (Polling): Consultando continuamente el bit GO/DONE (el
cual es limpiado por el convertidor cuando la conversin est completa).
b. Por interrupciones: Cuando la conversin termina, la bandera ADIF se
activa y esto genera una solicitud de interrupcin, la cual deber ser
atendida por una rutina de atencin a la interrupcin diseada para ello.
Leer el dato convertido D de los registros (ADRESH:ADRESL)
Para la siguiente conversin, esperar al menos 2TAD (Donde TAD es el tiempo de
conversin por bit).

3.3.3.- Los Registros de Control


A continuacin se presenta un resumen de los registros relacionados con la operacin
del convertidor:
R/W-0

1Fh
Bit

R/W-0

ADCS1 ADCS0
7

R/W-0

R/W-0

R/W-0

R/W-0

CHS2

CHS1

CHS0

U-0

R/W-0

GO/DONE

ADON

Registro ADCON0 (1Fh)


bits 7-6

ADCS1:ADCS0.- Seleccin de reloj de acuerdo a la siguiente tabla:


ADCS1
0
0
1
1

ADCS0
0
1
0
1

Frec. seleccionada

FOSC/2
FOSC/8
FOSC/32
FRC (oscilador RC interno)*

* El oscilador RC interno del convertidor tiene un TAD tpico de 4 seg, sin embargo,
puede variar entre 2 y 6 seg.. Este reloj es recomendable para operacin en modo
SLEEP, ya que este modo desconecta la frecuencia del reloj externo.
* Precaucin: El convertidor A/D no trabajar correctamente con un TAD menor que
TAD(mnimo) = 1.6seg. El usuario deber cuidar la eleccin del reloj adecuado para no violar
esta limitante.

bits 5-3

CHS2:CHS0.- Seleccin de canal analgico a convertir. Se selecciona uno


de los ocho canales AN0,...,AN7 colocando en estos tres bits el nmero
31

Descripcin Detallada del PIC16F87


binario correspondiente al canal deseado. (Los canales analgicos a usar
debern tener sus bits TRIS correspondientes seleccionados como
entradas).
bit 2

GO/DONE.- Bit de inicio y fin de conversin.- Con el convertidor encendido,


poniendo este bit en 1 se inicia la conversin del canal seleccionado. Este
bit permanece en 1 durante la conversin y es limpiado automticamente
por el convertidor al terminar la conversin.

bit 0

ADON.-Encendido del convertidor. Al poner este bit en 1 el convertidor se


enciende y al ponerlo en 0 se apaga y no consume corriente.
U-0

U-0

R/W-0

U-0

R/W-0

R/W-0

9Fh

ADFM

PCFG3

PCFG2

Bit

U-0

R/W-0

PCFG1 PCFG0
1

Registro ADCON1 (9Fh)


bit 7

ADFM.- Seleccin de formato del resultado. Al ponerlo en 1 se selecciona


resultado de 10 bits justificado a la derecha. Y con un 0 se selecciona
justificacin a la izquierda. En la siguiente seccin se explica con mayor
detalle.

Bits 3-0

PCFG3:PCFG0.- Bits de configuracin de las entradas del convertidor.


Configuran las patitas de entrada del convertidor de acuerdo a la siguiente
tabla, (en donde A = Entrada Analgica D = Entrada /Salida digital)

PCFG3: AN7(1) AN6(1) AN5(1) AN4/ AN3/


PCFG0 /RE2 /RE1 /RE0 RA5 RA3
0000
A
A
A
A
A
0001
A
A
A
A
VREF+
0010
D
D
D
A
A
0011
D
D
D
A
VREF+
0100
D
D
D
D
A
0101
D
D
D
D
VREF+
011x
D
D
D
D
D
1000
A
A
A
A
VREF+
1001
D
D
A
A
A
1010
D
D
A
A
VREF+
1011
D
D
A
A
VREF+
1100
D
D
D
A
VREF+
1101
D
D
D
D
VREF+
1110
D
D
D
D
D
1111
D
D
D
D
VREF+

AN2/ AN1/ AN0/


RA2 RA1 RA0
A
A
A
A
A
A
A
A
A
A
A
A
D
A
A
D
A
A
D
D
D
VREFA
A
A
A
A
A
A
A
VREFA
A
VREFA
A
VREFA
A
D
D
A
VREFD
A

VREF+ VREFVDD
RA3
VDD
RA3
VDD
VDD
VDD
RA3
VDD
RA3
RA3
RA3
RA3
VDD
RA3

VSS
VSS
VSS
VSS
VSS
VSS
VSS
RA2
VSS
VSS
RA2
RA2
RA2
VSS
RA2

Can(2)
/Refs
8/0
7/1
5/0
4/1
3/0
2/1
0/0
6/2
6/0
5/1
4/2
3/2
2/2
1/0
1/2

*Notas: (1) Estos tres canales no existen en los PIC16F873 / 76


(2) Esta columna indica el nmero de canales analgicos de entrada disponibles
y el nmero de canales analgicos usados como entradas de voltaje de
referencia.

3.3.4.- Los Registros de Resultados.

32

Descripcin Detallada del PIC16F87


El par de registros ADRESH:ADRESL (1Eh:9Eh) son cargados con el dato (D)
resultante de una conversin analgico / digital al terminar sta. Cada uno de estos
registros es de 8 bits, por lo tanto, juntos pueden guardar hasta 16 bits. Sin embargo,
como el resultado D es de 10 bits, el mdulo de conversin A/D permite justificarlo
(alinearlo) en la parte izquierda o derecha de los 16 bits disponibles, para elegir alguna
de las dos opciones se usa el bit ADFM (ADCON1<7>) como se muestra en la figura
siguiente
Resultado (D) de 10 bits

ADFM=1

ADFM=0

0000 00
7

0000 00
1

07

ASDRESH

ADRESL

07

ASDRESH

Resultado (D) de 10 bits

ADRESL

Resultado (D) de 10 bits

Caractersticas Elctricas del convertidor.- Las siguientes son algunas de las


especificaciones ms importantes, y son vlidas para los PIC16F87X-04, PIC16F87X10, PIC16F87X-20, PIC16LF87X-04:
Caracterstica
VREF+-VREFVREF+
VREFVoltaje analgico VAIN
Impedancia de la fuente de seal externa

mnimo
2v
VDD-2.5v
VSS-0.3v
VSS-0.3v
-

ZAIN

Corriente promedio consumida

Estndar

por el convertidor IAD

Extendido

tpico
220A
90A

mximo
VDD+0.3v
VDD+0.3v
VREF+-2v
VREF++0.3v
10 K
-

Ejemplo 13.- Adquisicin de una seal analgica por poleo.


El siguiente programa realiza la conversin repetitiva de una seal analgica conectada
al canal AN0. El dato obtenido en cada conversin es convertido a 4 cdigos ASCII de
los respectivos 4 dgitos hexadecimales equivalentes para poder desplegarlos en la
pantalla de una PC que los recibir a travs de su puerto serie RS232.
;************************************************************************
;* Este programa realiza la conversin de una seal analgica conectada *
;* al canal AN0 y enva a travs del puerto serie el resultado de la
*
;* conversin en forma de 4 dgitos hexadecimales.
*
;************************************************************************
;
Include "p16f877.inc"
cont EQU 0x20
msnib EQU 0x22
lsnib EQU 0x23
org 0x0000
inic CALL initrans
;inicializa el puerto serie para transmisin

33

Descripcin Detallada del PIC16F87


BSF STATUS,RP0
CLRF ADCON1
BSF ADCON1,ADFM
BSF TRISA,0
BCF STATUS,RP0
MOVLW 0x01
MOVWF ADCON0
ciclo CALL pausa
BSF ADCON0,GO
espera BTFSC ADCON0,DONE
GOTO espera
MOVF ADRESH,W
CALL Envbyte
BSF STATUS,RP0
MOVF ADRESL,W
CALL Envbyte
MOVLW 0x0D
CALL envia
MOVLW 0x0A
CALL envia
GOTO ciclo

;Banco 1
;configura 8 canales analgicos, VREF+=VDD y VREF-=VSS
;Elije resultado con justificacin a la derecha
;configura como entrada el canal digital RA0
;Banco 0
;Selecciona el canal AN0, reloj de conversin Fosc/2
;y enciende el convertidor
;espera 30 seg a que pase el tiempo de adquisicin
;inicia conversin
;Espera a que termine la conversin
;Carga en W el Byte alto del resultado
;enva el byte por el puerto serie
;banco 1
;Carga en W el Byte bajo del resultado
;enva el byte por el puerto serie
;carga cdigo de retorno de lnea <CR>
;lo enva
;carga cdigo de avance de lnea <LF>
;lo enva
;repite

;***************************************************************
; Subrutina que enva el byte en W por el puerto serie, separado
; en los cdigos ASCII de sus dos nibbles hexadecimales
;***************************************************************
Envbyte:
MOVWF msnib
MOVWF lsnib
SWAPF msnib,1
MOVLW 0x0F
ANDWF msnib,1
ANDWF lsnib,1
MOVF msnib,W
CALL asc
CALL envia
MOVF lsnib,W
CALL asc
CALL envia
RETURN
asc
ADDWF PCL,1

;pone byte en msnib


;y una copia en lsnib
;intercambia nibbles en lsnib
;mscara para limpiar el nibble alto
;limpia parte alta de msnib
;limpia parte alta de lsnib
;carga msnib en W
;obtiene cdigo ASCII equivalente
;lo enva por el puerto serie
;carga lsnib en W
;obtiene cdigo ASCII equivalente
;lo enva por el puerto serie

;Calcula el cdigo a retornar


;Saltando W instrucciones adelante
DT "0123456789ABCDEF"

;************************************************************
; Subrutina de pausa de aprox. 30 seg (con Fosc=14.7456 MHZ)
;************************************************************
pausa MOVLW 0x23
;Carga dato para 30 seg.
MOVWF cont
;inicializa contador con el dato
rep
DECFSZ cont,1
;Decrementa contador y escapa si cero
GOTO rep
;si no es cero, repite
esc
RETURN
;regresa de esta subrutina
;****************************************************************
;Subrutina para inicializar el puerto serie USART como transmisor
;a 9600 Bauds, considerando un cristal de reloj de 14.7456 MHZ
;****************************************************************
initrans:
BCF STATUS,RP1
BSF STATUS,RP0
;banco 1
BCF TXSTA,BRGH
;pone bit BRGH=0 (velocidad baja)
MOVLW 0x17
;valor para 9600 Bauds (Fosc=14.7456 Mhz)
MOVWF SPBRG
;configura 9600 Bauds
BCF TXSTA,SYNC
;limpia bit SYNC (modo asncrono)
BSF TXSTA,TXEN
;pone bit TXEN=1 (habilita transmisin)

34

Descripcin Detallada del PIC16F87


BCF STATUS,RP0
BSF RCSTA,SPEN
RETURN

;regresa al banco 0
;pone bit SPEN=1 (habilita puerto serie)

;***************************************************************
;Subrutina para enviar el byte guardado en W por el puerto serie
;***************************************************************
envia BSF STATUS,RP0
;banco 1
esp
BTFSS TXSTA,TRMT
;checa si el buffer de transmisin
GOTO esp
;si est ocupado espera
BCF STATUS,RP0
;regresa al banco 0
MOVWF TXREG
;enva dato guardado en W
RETURN
end

Observacin. La seal conectada a la lnea AN0 deber estar en el rango de


VSS a VDD, para fines de prueba puede ser usado un potencimetro (de 1 a 10
K) como se muestra en la figura siguiente
V DD

5K
AN0

PIC
Vss

35

Descripcin Detallada del PIC16F87


33..44..-- EEll M
Mdduulloo T
Teem
mppoorriizzaaddoorr
3.4.1.- Descripcin General del Mdulo Temporizador (Timer)
Los PIC 16F87X poseen un mdulo para el manejo preciso y eficiente de operaciones
que involucran tiempo o conteo. Este mdulo consta de:

Tres contadores/temporizadores denominados TMR0, TMR1 y TMR2


Dos mdulos CCP (Captura, Comparacin y PWM (Modulacin de ancho de
pulso) denominados CCP1 y CCP2

En la siguiente tabla se resumen las principales caractersticas de los mdulos


mencionados:
Mdulo

TMR0

TMR1

TMR2

CCP1 y
CCP2

Caractersticas

TMR0 es un Contador/Temporizador de 8 bits


Leble y escribible
Reloj interno o externo
Seleccin de flanco activo en el reloj externo
Preescalador de 8 bits programable
Solicitud de interrupcin opcional en el desbordamiento (de
FFh a 00h)
TMR1 es un Contador/Temporizador de 16 bits
Leble y escribible
Reloj interno o externo
Solicitud de interrupcin opcional en el desbordamiento (de
FFFFh a 0000h)
Reinicializacin opcional desde los mdulos CCP
TMR2 es un Contador/Temporizador de 8 bits
Dispone de un registro de periodo de 8 bits (PR2)
Leble y escribible
Preescalador programable
Postescalador programable
Solicitud de interrupcin opcional al coincidir TMR2 y PR2
Posibilidad de generar impulsos al mdulo SSP (puerto serie
sncrono)
Modo de captura
Modo de comparacin
Modo PWM (modulacin de ancho de pulso)

3.4.2.- El Mdulo del Timer 0.


El Timer 0 es un contador / temporizador de 8 bits. El registro principal de este mdulo
es TMR0 (01h, 101h). Este registro se incrementa continuamente a una frecuencia
seleccionable manejada por un preescalador y el reloj interno Fosc/4 (modo
temporizador) o bien, por un preescalador y una seal externa (modo contador).
En la siguiente figura se muestra un diagrama de bloques de este mdulo, en donde se
indican los bits que afectan su operacin y la manera en que lo hacen.
36

Descripcin Detallada del PIC16F87


Fosc/4

Bus de datos
0

RA4/T0CKI

M
U
X

1
T0SE

1
0

T0CS

M
U
X

Preescalador

PSA

PS2,PS1,PS0

TMR0

PSA

T0IF

1
Timer del
Watchdog

M
U
X

M
U
X

Time out
del
watchdog

PSA

3.4.2.1.-El modo Temporizador


En el modo temporizador la seal de reloj que controla el incremento del registro TMR0
es la frecuencia Fcy = Fosc/4, la cual puede ser dividida opcionalmente por el
preescalador si as se desea. Como se puede ver en la figura anterior, este modo es
seleccionado al limpiar el bit T0CS (OPTION_REG<5>). En este modo, el contenido del
registro TMR0 se incrementar a la frecuencia Fcy dividida de acuerdo al preescalador,
sin embargo, si se realiza una escritura al registro TMR0, su incremento es inhibido por
los siguientes dos ciclos de instruccin (Tcy).
3.4.2.2.- El modo Contador
En el modo contador, la seal que controla los incrementos del registro TMR0 es una
seal externa que proviene de la patita T0CKI. En la figura anterior se puede ver que
este modo se selecciona poniendo el bit T0CS en alto. Se puede seleccionar la
transicin que provoca los incrementos mediante el bit Timer0 Source Edge Select
T0SE (OPTION_REG<4>), limpiando este bit se selecciona la transicin de subida,
mientras que al ponerlo en alto se selecciona la de bajada.
Observacin: En este modo, la seal conectada a TOCKI es muestreada durante los ciclos Q2 y Q4 del
reloj interno, por ello es necesario que permanezca en alto al menos por 2 Tosc ms un
pequeo retardo de 20nseg y lo mismo en bajo. (es decir, seales demasiado estrechas
(rpidas) no podrn ser detectadas).

3.4.2.3.- La Bandera T0IF


El registro TMR0 se incrementa continuamente en cualquiera de sus dos modos, desde
00h hasta FFh y en la siguiente cuenta se reinicia en 00h y as sucesivamente.
Al momento del reinicio se activa la bandera T0IF (INTCON<2>) ponindose en 1. Esta
activacin puede usarse de dos maneras:

37

Descripcin Detallada del PIC16F87


para solicitar una interrupcin
para ser consultada por poleo
En ambos casos debe tenerse en cuenta que para poder detectar una activacin (un 1)
en esta bandera, previamente habr que limpiarla por software. Esto debe realizarse en
la inicializacin del Timer y despus de que un reciclo la ha activado. Lo ltimo puede
hacerse en la rutina de atencin a la interrupcin, o bien, en la rutina que la consulta por
poleo (segn sea el caso).
3.4.2.4.- El preescalador
El preescalador es un divisor de frecuencia de mdulo seleccionable. Como se puede
ver en la figura anterior, el preescalador est compartido entre el timer0 y el mdulo
watchdog, sin embargo slo puede conectarse a uno de los dos y esto se establece
mediante el bit PSA (OPTION_REG<3>), as, con este bit en alto el preescalador es
asignado al reloj del watchdog, mientras que con un nivel bajo en PSA el preescalador
dividir la frecuencia que maneja al timer 0.
La seleccin del mdulo (valor de divisin de frecuencia) del preescalador se puede
realizar mediante los bits PS2,PS1,PS0 (OPTION_REG<2:0>) de acuerdo a la siguiente
tabla
PS2 PS1 PS0

0
0
0
0
1
1
1
1

0
0
1
1
0
0
1
1

0
1
0
1
0
1
0
1

Divisor
(timer 0)

Divisor
(Watchdog)

1/2
1/4
1/8
1/16
1/32
1/64
1/128
1/256

1/1
1/2
1/4
1/8
1/16
1/32
1/64
1/128

Observacin: Cuando el preescalador est asignado al timer 0, cualquier escritura al registro TMR0
(cualquier BCF, BSF, MOVWF, CLRF, etc) limpiar el preescalador. En forma similar,
cuando est asignado al watchdog, una instruccin CLRWDT limpiar no solo el timer del
watchdog, sino tambin el preescalador.

A manera de resumen se presenta a continuacin una descripcin de los bits del


registro OPTION_REG que tienen relacin con el timer 0:
R/W-1

81h,181h RB PU
Bit:

R/W-1

R/W-1

R/W-1

R/W-1

R/W-1

R/W-1

R/W-1

INTEDG

T0CS

T0SE

PSA

PS2

PS1

PS0

Registro OPTION_REG (81h, 181h)


bits 5

T0CS.- Bit de seleccin de la fuente de reloj para incrementar TMR0. Un 1


en este bit selecciona como reloj la patita T0CKI (modo contador),
38

Descripcin Detallada del PIC16F87


mientras que un 0 selecciona el reloj del ciclo de instruccin interno
(CLKout) (modo temporizador).
bit 4

T0SE.- Bit de seleccin de transicin activa del reloj en modo contador. Un


1 en este bit selecciona el incremento de TMR0 en la transicin de alto a
bajo de T0CKI, mientras que un 0 selecciona la la transicin de bajo a alto.

bit 3

PSA.- Bit de asignacin del preescalador. Un 1 en este bit asigna el


preescalador al watchdog y un 0 lo asigna al Timer0.

bits 2:0

PS2:PS0.- Bits de seleccin del valor del preescaler (ver tabla anterior).

Ejemplo 14.- Manejo del Timer 0 como contador.


El siguiente programa realiza el conteo de el nmero de veces que produce una
transicin de bajo a alto en la patita T0CKI. El valor del contador se incrementar una
vez por cada dos transiciones y ser enviado a travs del puerto serie para ser
desplegado en la pantalla de una PC, usando las subrutinas mostradas en el ejemplo
13.
;****************************************************************************
;* Este programa realiza el conteo de una seal conectada a la patita T0CKI *
;* el valor del contador lo enva a travs del puerto serie para su des*
;* pliegue en una PC
*
;****************************************************************************
Include "p16f877.inc"
org 0x0000
inic CALL initrans
;inicializa el puerto serie para transmisin
BCF STATUS,RP0
;Banco 0
CLRF TMR0
;inicializa la cuenta de TMR0
BSF STATUS,RP0
;Banco 1
MOVLW 0xE0
;dato de configuracin para el timer0
MOVWF OPTION_REG
;configura modo contador, transicin positiva,
;preescalador 1/2 asignado a timer0
BCF STATUS,RP0
;Banco 0
ciclo MOVF TMR0,W
;lee cuenta actual
CALL Envbyte
;enva el valor por el puerto serie
MOVLW 0x0D
;carga carcter <CR>
CALL envia
;lo enva
MOVLW 0x0A
;carga carcter <LF>
CALL envia
;lo enva
GOTO ciclo
;repite

;***************************************************************
; Subrutina que enva el byte en W por el puerto serie, separado
; en los cdigos ASCII de sus dos nibbles hexadecimales
;***************************************************************
msnib EQU 0x22
lsnib EQU 0x23
Envbyte:
MOVWF msnib
MOVWF lsnib
SWAPF msnib,1
MOVLW 0x0F
ANDWF msnib,1
ANDWF lsnib,1
MOVF msnib,W
CALL asc

;pone byte en msnib


;y una copia en lsnib
;intercambia nibbles en lsnib
;mscara para limpiar el nibble alto
;limpia parte alta de msnib
;limpia parte alta de lsnib
;carga msnib en W
;obtiene cdigo ASCII equivalente

39

Descripcin Detallada del PIC16F87

asc

CALL envia
MOVF lsnib,W
CALL asc
CALL envia
RETURN
ADDWF PCL,1

;lo enva por el puerto serie


;carga lsnib en W
;obtiene cdigo ASCII equivalente
;lo enva por el puerto serie

;Calcula el cdigo a retornar


;Saltando W instrucciones adelante
DT "0123456789ABCDEF"
;****************************************************************
;Subrutina para inicializar el puerto serie USART como transmisor
;a 9600 Bauds, considerando un cristal de reloj de 14.7456 MHZ
;****************************************************************
initrans:
BCF STATUS,RP1
BSF STATUS,RP0
;banco 1
BCF TXSTA,BRGH
;pone bit BRGH=0 (velocidad baja)
MOVLW 0x17
;valor para 9600 Bauds (Fosc=14.7456 Mhz)
MOVWF SPBRG
;configura 9600 Bauds
BCF TXSTA,SYNC
;limpia bit SYNC (modo asncrono)
BSF TXSTA,TXEN
;pone bit TXEN=1 (habilita transmisin)
BCF STATUS,RP0
;regresa al banco 0
BSF RCSTA,SPEN
;pone bit SPEN=1 (habilita puerto serie)
RETURN
;***************************************************************
;Subrutina para enviar el byte guardado en W por el puerto serie
;***************************************************************
envia BSF STATUS,RP0
;banco 1
esp
BTFSS TXSTA,TRMT
;checa si el buffer de transmisin
GOTO esp
;si est ocupado espera
BCF STATUS,RP0
;regresa al banco 0
MOVWF TXREG
;enva dato guardado en W
RETURN
end

Observacin. Mediante el programa anterior podemos realizar el conteo de pares de


rebotes provocados por un botn pulsador, basta con conectar la salida de dicho
botn a la patita T0CKI. Al hacer lo anterior se ver que por cada pulsacin del botn se
incrementa la cuenta no de uno en uno, sino en un valor mayor por el efecto de los
rebotes. Esto tambin quiere decir, que si no deseamos que el contador se vea
afectado por el rebote de la seal a contar, se deber incluir un limpiador de rebotes por
hardware, externo al PIC.
Ejemplo 15.- Manejo del Timer 0 como temporizador.
El siguiente programa utiliza el timer 0 para realizar una pausa de mxima duracin, la
cual se intercala en el encendido / apagado de un LED conectado a la patita RC0, es
decir, el LED parpadear a la frecuencia F que se puede calcular como sigue:
F = 1/(TH+TL)
En donde TH es el tiempo de encendido y TL es el tiempo de apagado del LED. Como
en el ejemplo son iguales, usaremos slo T = TH = TL, por lo tanto
F = 1/(2T)

40

Descripcin Detallada del PIC16F87


Para calcular T con una frecuencia de reloj Fosc dada y un valor del preescalador 1/M,
para un ciclo de N incrementos del timer 0 tendremos que la duracin (Tciclo) del ciclo
ser
T = Tciclo = N*M*(4/Fosc)
As, para una duracin mxima M = 256, N = 256 tendremos:
TMAX = 262144/Fosc
Para un reloj de 14.7456 Mhz tendremos
TMAX = 17.777... mseg
Y la frecuencia de parpadeo del LED ser F = 28.125 Hertz.
;*****************************************************************
;* Este programa hace parpadear un LED conectado a la patita RC0 *
;* Usa el timer 0 para generar una pausa de 17.777777 mseg de
*
;* duracin (supone un cristal de 14.7456 Mhz). La frecuencia de *
;* parpadeo del LED es de 28.125 Hertz aprox.
*
;*****************************************************************
inic

rep

Include "p16f877.inc"
org 0x0000
BSF STATUS,RP0
;Banco1
BCF TRISC,0
;patita RC0 como salida
BCF STATUS,RP0
;Banco 0
BSF PORTC,0
;enciende LED
CALL pausa
;pausa de 17.77 mseg
BCF PORTC,0
;apaga LED
CALL pausa
;pausa de 17.77 mseg
GOTO rep

;* Subrutina de pausa de 17.77 mseg


;*************************************
N1
EQU 0x00
pausa MOVLW N1
;nmero de incrementos del timer
MOVWF TMR0
;inicializa la cuenta de TMR0
BCF INTCON,T0IF
;limpia bandera de sobreflujo
BSF STATUS,RP0
;Banco 1
MOVLW 0xC7
;dato de configuracin para el timer0
MOVWF OPTION_REG
;modo temporizador, preescalador 1/256 asignado a timer0
BCF STATUS,RP0
;Banco 0
ciclo BTFSS INTCON,T0IF ;checa bandera de sobreflujo (cuenta=256)
GOTO ciclo
;si no se ha activado, espera
BCF INTCON,T0IF
;si ya se activ, la desactiva
RETURN
;retorna
end

Observacin: La rutina de pausa se puede modificar para una duracin de N ciclos en general,
simplemente definiendo como N1 lo que le falta a N para ser 256, es decir:
N1 = 256-N

3.4.3.- El Mdulo del Timer 1.


41

Descripcin Detallada del PIC16F87


El Timer 1 a diferencia del Timer 0 es un contador / temporizador de 16 bits. El conteo
es realizado por dos registros de 8 bits: (TMR1H (0Fh) y TMR1L (0Eh)), estos dos
registros son tanto lebles como escribibles. Al par de registros TMR1H:TMR1L los
denominaremos por comodidad como si fueran un solo registro de 16 bits (TMR1).
As, el registro TMR1 se incrementa de 0000h a FFFFh y en la siguiente cuenta se
reinicia en 0000h y as sucesivamente, al reciclarse se activa (en alto) la bandera
TMR1IF (PIR1<0>), la cual puede ser utilizada para generar una interrupcin, o bien,
para ser consultada por poleo, teniendo las mismas precauciones que ya se explicaron
antes para la bandera T0IF.
En la siguiente figura se muestra un diagrama de bloques de este mdulo, en donde se
indican los bits que afectan su operacin y la manera en que lo hacen.

3.4.3.1.- Modo temporizador


En este modo el Timer 0 se incrementa (si no se considera preescalador) en cada ciclo
de instruccin (a la frecuencia Fosc/4). Este modo se selecciona limpiando el bit
TMR1CS (T1CON<1>).
El preescalador que se puede intercalar entre el reloj Fosc/4 y el registro TMR1 puede
tener slo uno de 4 valores: 1/1, 1/2, 1/4 y 1/8.
3.4.3.2.- Modo contador
El Timer 1 tambin puede operar como contador, en este ltimo caso, la entrada a
contar se toma de la patita externa RC0/T1OSO/T1CKI. En estos apuntes no se
describe este modo.
3.4.3.3.- Otras caractersticas

42

Descripcin Detallada del PIC16F87


El Timer 1 tambin posee un bit para habilitacin / deshabilitacin, este es el bit
TMR1ON (T1CON<0>) y habilita en alto.
Adems, el Timer 1 posee una entrada interna de RESET, el cual puede ser activado
por uno cualquiera de los mdulos CCP que se describirn ms adelante.
A continuacin se describe el principal registro relacionado con el Timer 1 y todos sus
bits, excepto los que tienen que ver con el modo contador:
U-0

U-0

10h

Bit:

R/W-0

R/W-0

R/W-0

R/W-0

T1CKPS1 T1CKPS0 T1OSCEN T 1 SYNC


5

R/W-0

R/W-0

TMR1CS TMR1ON
1

Registro T1CON (10h)


bits 5:4

T1CKPS1:T1CKPS0.- Bits de seleccin del valor del divisor de frecuencia


del preescalador:
1 1 = divisor 1/8
1 0 = divisor 1/4
0 1 = divisor 1/2
0 0 = divisor 1/1
Observacin: La cuenta interna del preescalador es limpiada cuando se hace una
escritura a cualquiera de los registros TMR1H o TMR1L

bit 1

TMR1CS.- Bit de seleccin de la fuente de reloj


1 = Modo contador (fuente de reloj: patita RC0/T1OSO/T1CKI)
0 = Modo Temporizador (fuente de reloj Fosc/4)

bit 0

TMR1ON.- Bit de habilitacin / deshabilitacin del Timer 1:


1 = habilita Timer 1
0 = Deshabilita Timer 1

Ejemplo 16.- Manejo del Timer 1 como temporizador.


A continuacin se describe un programa similar al ejemplo 16, en el cual se utiliza el
Timer 1 para realizar una pausa de mxima duracin, la cual se intercala en el
encendido / apagado de un LED conectado a la patita RC0, es decir, el LED parpadear
a la frecuencia F que se puede calcular como sigue:
F = 1/(TH+TL)
En donde TH es el tiempo de encendido y TL es el tiempo de apagado del LED. Como
en el ejemplo son iguales, usaremos slo T = TH = TL, por lo tanto
F = 1/(2T)

43

Descripcin Detallada del PIC16F87


Para calcular T con una frecuencia de reloj Fosc dada y un valor del preescalador 1/M,
para un ciclo de N incrementos del registro TMR1 tendremos que la duracin (Tciclo)
del ciclo ser
T = Tciclo = N*M*(4/Fosc)
As, para una duracin mxima M = 8, N = 65536 tendremos:
TMAX = 2,097,152/Fosc
Para un reloj de 14.7456 Mhz tendremos
TMAX = 142.222... mseg
Y por lo tanto la frecuencia de parpadeo del LED ser F = 3.515625 Hertz.
;*****************************************************************
;* Este programa hace parpadear un LED conectado a la patita RC0 *
;* Usa el timer 1 para generar una pausa de 142.222.. mseg de
*
;* duracin (supone un cristal de 14.7456 Mhz). La frecuencia de *
;* parpadeo del LED es de 3.515625 Hertz aprox.
*
;*****************************************************************
inic

rep

Include "p16f877.inc"
org 0x0000
BSF STATUS,RP0
;Banco1
BCF TRISC,0
;patita RC0 como salida
BCF STATUS,RP0
;Banco 0
BSF PORTC,0
;enciende LED
CALL pausa
;pausa de 71.11 mseg
BCF PORTC,0
;apaga LED
CALL pausa
;pausa de 71.11 mseg
GOTO rep

;* Subrutina de pausa de 71.111 mseg


;*************************************
N1
EQU 0x00
N0
EQU 0x00
pausa MOVLW N1
;nmero de incrementos del timer msb
MOVWF TMR1H
;inicializa la cuenta de TMR1
MOVLW N0
;nmero de incrementos del timer lsb
MOVWF TMR1L
;inicializa la cuenta de TMR1
BCF PIR1,TMR1IF
;limpia bandera de sobreflujo
MOVLW 0x31
;dato de configuracin para el timer1
MOVWF T1CON
;modo temporizador, preescalador 1/8, habilita timer 1
ciclo BTFSS PIR1,TMR1IF ;checa bandera de sobreflujo (cuenta=65536)
GOTO ciclo
;si no se ha activado, espera
BCF PIR1,TMR1IF
;si ya se activ, la desactiva
RETURN
;retorna
end

Observacin 1: El programa es idntico al ejemplo 15, lo nico que cambia es la subrutina de pausa, la
cual ahora se ha realizado con el timer 1 y no con el Timer 0
Observacin 2: La rutina de pausa se puede adaptar para una duracin de N ciclos en general,
simplemente definiendo como N1:N0 lo que le falta a N para ser 65536, es decir:
N1:N0 = 65536-N

44

Descripcin Detallada del PIC16F87


3.4.4.- El Mdulo del Timer 2.
El Timer es un temporizador (sin opcin de trabajar como contador) de 8 bits. Su
registro principal denominado TMR2 (11h) es un registro de 8 bits que se incrementa
continuamente a la frecuencia seleccionada de Fosc/4 dividida por un preescalador.
En la siguiente figura se muestra un diagrama de bloques del mdulo del Timer2.
Salida de
TMR2

Fosc/4

Preescalador
1/1, 1/4, 1/16

T2CKPS1:T2CKPS0

Postescalador
1:1 a 1/16

Registro TMR2

Comparador

Activa
TMR2IF

T2OUPS3:T2OUPS0

Registro PR2

3.4.4.1.- El preescalador
La frecuencia que incrementa al registro TMR2 puede ser dividida por un preescalador
por un factor de 1/1, 1/4 o 1/16, seleccionable por los bits T2CKPS1:T2CKPS0
(T2CON<1:0>)
3.4.4.2.- El Registro de comparacin o de Periodo
En operacin, el contenido del registro TMR2 se compara continuamente con un
registro de periodo denominado PR2 (92h) cuyo valor podemos establecer por software.
Cada vez que la cuenta de TMR2 es igual a PR2, se reinicia el conteo en TMR2 desde
cero, y adems se genera una seal de salida, la cual es tratada por un postescalador,
para poder generar una seal TMR2IF (PIR1<1>) que puede ser usada para solicitar
una interrupcin, o para ser leda por poleo.
3.4.4.3.- El Postescalador
El postescalador divide la frecuencia con que ocurre una activacin de la bandera
TMR2IF, es decir, si el valor del postescalador es 1/1, esta bandera se activar cada
vez que TMR2 se reinicie, en cambio, si es 1/16 (por ejemplo), TMR2IF se activar cada
16 reinicios de TMR2. En forma similar a los otros dos Timers, esta bandera debe ser
limpiada previamente, si se quiere detectar su activacin, esto puede ser hecho en la
rutina de atencin a la interrupcin, o bien en la rutina que la detecta por poleo.
El valor de divisin del postescalador puede establecerse por software mediante los bits
T2OUPS3:T2OUPS0 (T2CON<6:3>).

45

Descripcin Detallada del PIC16F87


A continuacin se describe el principal registro relacionado con el Timer 2 y todos sus
bits.
U-0

12h
Bit:

R/W-0

R/W-0

R/W-0

R/W-0

R/W-0

R/W-0

R/W-0

- T2OUPS3 T2OUPS2 T2OUPS1 T2OUPS0 TMR20N T2CKPS1 T2CKPS0


7

Registro T2CON (12h)


bits 6:3

T2OUPS3:T2OUPS0.- Bits de seleccin del valor del divisor de frecuencia


del postescalador, de acuerdo a la siguiente tabla:
0 0 0 0 = divisor 1/1
0 0 0 1 = divisor 1/2
0 0 1 0 = divisor 1/3

1 1 1 1 = divisor 1/116
Observacin: La cuenta interna del postescalador y el preescalador es limpiada cuando
ocurre cualquiera de los siguientes eventos: Una escritura a alguno de los registros TMR2
o T2CON o bien, un Reset del sistema de cualquier tipo (POR, MCLR, WDT, o BOR).

bit 2

TMR2ON.- Bit de encendido del Timer 2


1 = Enciende (energiza) el Timer 2
0 = Apaga (desconecta) el Timer 2

bits 1:0

T2CKPS1:T2CKPS0.- Bits de configuracin del valor del preescalador de


acuerdo a la siguiente tabla:
0 0 = divisor 1/1
0 1 = divisor 1/4
1 x = divisor 1/16

Ejemplo 17.- Manejo del Timer 2 como temporizador.


Cul es la mxima duracin de una pausa realizada mediante el Timer 2, usando el
mismo esquema de los ejemplos 15 y 16 de dejar pasar el tiempo transcurrido en una
sla activacin de TMR2IF?.
Solucin.
Sea T la duracin de la pausa, con una frecuencia de reloj Fosc dada, un valor del
preescalador 1/M, y un valor del postescalador 1/P. Para un ciclo de N incrementos del
registro TMR2, es decir, para un valor de N del registro de periodo PR2, tendremos que
la duracin de la pausa dada por
T = N*M*P*(4/Fosc)
As, para una duracin mxima P = M = 16, N = 256 tendremos:
TMAX = 262144/Fosc
46

Descripcin Detallada del PIC16F87


Para un reloj de 14.7456 Mhz tendremos
TMAX = 17.777... mseg

3.5.- Los Mdulos de CCP (Captura / Comparacin / PWM)


El PIC16F87X posee dos mdulos CCP, denominados CCP1 y CCP2. Ambos mdulos
son prcticamente idnticos con la excepcin de la operacin del disparo de evento
especial. Cada uno de estos dos mdulos poeen un registro de 16 bits, el cual puede
operar como:

Registro de captura de 16 bits


Registro de comparacin de 16 bits
Registro de Ciclo de Trabajo del mdulo PWM.

Cada modo de operacin requiere como recurso uno de los timers del PIC. En la
siguiente tabla se muestran los timers usados por cada modo:
Modo de operacin Recurso
del CCP
utilizado
Captura
Timer 1
Comparacin
Timer 1
PWM
Timer 2
A continuacin se da un breve resumen de los registros relacionados con cada mdulo:
El Mdulo CCP1.
El registro principal de este mdulo (CCPR1) se compone de dos registros de 8 bits,
denominados CCPR1H (16h) (parte ms significativa) y CCPR1L (15h) (parte menos
significativa). La operacin del mdulo se controla mediante el registro CCP1CON y el
disparo de evento especial, el cual es generado al alcanzarse la igualdad en un registro
de comparacin resetear el Timer 1.
El Mdulo CCP2.
El registro principal de este mdulo (CCPR2) se compone de dos registros de 8 bits,
denominados CCPR2H (parte ms significativa) y CCPR2L (parte menos significativa).
La operacin del mdulo se controla mediante el registro CCP2CON y el disparo de
evento especial, el cual es generado al alcanzarse la igualdad en un registro de
comparacin resetear el Timer 1 e iniciar una conversin analgico/digital (si el
mdulo convertidor A/D est habilitado).
Seleccin del modo de operacin

47

Descripcin Detallada del PIC16F87


La seleccin del modo en que trabajara el mdulo CCPx se realiza mediante los cuatro
bits menos significativos del registro CCPxCON, es decir, mediante los bits
CCPxM3:CCPx0 (CCP<CON<3:0>) de acuerdo a la siguiente tabla
CCPxM3:CCPxM0

0000
0100
0101
0110
0111
1000
1001
1010
1011
11xx

Modo seleccionado
Captura/Comparacin/PWM deshabilitados
Captura cada transicin de bajada
Captura cada transicin de subida
Captura cada cuarta transicin de subida
Captura cada 16 transiciones de subida
Comparacin, pone salida cada coinidencia
Comparacin, limpia salida cada coincidencia
Comparacin, genera interrupcin cada coincidencia (salida inalterada)
Comparacin, dispara evento espacial (CCP1 resetea TMR1; CCP2
resetea TMR1 y arranca una conversin A/D).
Modo PWM

A continuacin se describe a detalle cada uno de los modos de operacin, comenzando


con el modo PWM. La descripcin se realiza slo para el mdulo CCP1, ya que es
prcticamente igual al CCP2.
3.5.1.- Modo PWM (Modulacin de Ancho de Pulso).
En este modo se puede producir una salida de frecuencia fija seleccionable modulada
en ancho de pulso (o ciclo de trabajo) con una resolucin de 10 bits, a travs de la
patita RC2/CCP1, como se muestra en la figura siguiente

Periodo

RC2/CCP1
Ciclo de Trabajo
(C.T.)

TMR2=PR2

TMR2=PR2
TMR2=C.T.

Debido a que la patita CCP1 est multiplexada con RC2, este bit del puerto C deber
ser configurado como salida (TRISC<2>=0) para poder usar la salida CCP1.
En la siguiente figura se muestra un diagrama de bloques simplificado que resume la
operacin bsica del PWM.

48

Descripcin Detallada del PIC16F87


CCP1CON<5:4>
Carga C.T.
en CCPR1H

CCPR1L
Registros de
C.T. (Ciclo
de Trabajo)

CCPR1H
RC2/CCP1

Comparador

TMR2

(Nota 1)

TRISC<2>
Comparador

PR2

Limpia TMR2 y
pone patita
CCP1=1

(Nota 1): los 8 bits del registro TMR2 son concatenados con 2 bits del preescalador
para crear una base de tiempo de 10 bits

3.5.1.1.- Control del Periodo del PWM


Para especificar el periodo del PWM se usa el registro PR2, de manera que el valor del
periodo ser:
PeriodoPWM = (PR2+1)*4*TOSC*M
Donde 1/M es el valor del preescalador del Timer 2.
Cuando el valor en TMR2 alcanza el valor PR2 los siguientes tres eventos ocurren en el
siguiente ciclo (Ver figura anterior):

El registro TMR2 es limpiado


La patita CCP1 es puesta en alto (Excepto si el ciclo de Trabajo del PWM vale
cero).
El Ciclo de Trabajo es cargado de CCPR1L (15h) a CCPR1H (16h).

De esta manera, de acuerdo a la figura anterior, el siguiente valor de comparacin para


TMR2 en el comparador de 10 bits es el Ciclo de Trabajo, el cual al alcanzarse limpiar
la patita CCP1.
3.5.1.2.- Control del Ciclo de Trabajo del PWM
El ciclo de Trabajo se especifica escribiendo un valor de 10 bits al registro CCPR1L (los
8 bits ms significativos (msb)) y los dos bits menos significativos (lsb) a
CCP1CON<5:4>
este
valor
de
10
bits
lo
representaremos
como

49

Descripcin Detallada del PIC16F87


CT=CCPR1L:CCP1CON<5:4>. El valor de tiempo que dura el ciclo de trabajo para un
valor del preescalador de 1/M, se calcula de acuerdo a la siguiente ecuacin:
TPWM = CT*TOSC*M
Como se puede ver en la figura anterior, el valor que determina la duracin de C.T. del
PWM no es el cargado en CT (CCPR1L), sino en CCPR1H, el cual slo se actualiza
copiando el valor de CT en el momento en que TMR2 alcanza el valor de PR2 (es decir,
cada vez que se completa un periodo). Por ello, aunque CCPR1L puede ser escrito en
cualquier momento, el Ciclo de Trabajo solo se actualiza hasta que termina el periodo
que est en transcurso.
No hay otra manera de escribir al registro CCPR1H, ya que este es un registro de slo
lectura.
Cuando el valor de TMR2 (concatenado con dos bits internos) alcanza el valor de
CCPR1H (concatenado con dos bits internos tambin) la patita CCP1 es limpiada (ver
figura anterior.
Como puede verse, el nmero de divisiones que se pueden tener en un Ciclo de
Trabajo ser 2r, donde r es el nmero de bits usados, por lo tanto su duracin mxima
ser este nmero de divisiones multiplicada por la duracin del ciclo ms pequeo del
sistema TOSC. Por lo tanto:
TPWM = (2 r)* TOSC*M
Sin embargo, dependiendo del valor de Ciclo de trabajo mximo (TPWM) deseado, no
ser posible realizar las 2r divisiones y por lo tanto no se podrn usar los r bits de
resolucin. O al revs, si se elige una resolucin deseada r no ser posible tener
cualquier Ciclo de Trabajo mximo (TPWM) Deseado.

Adems, si se elige TPWM mayor que el periodo del PWM (PeriodoPWM) la patita
CCP1 no ser limpiada (y por lo tanto no funcionar el PWM).
Ejemplo: As, por ejemplo, suponiendo un cristal de 20 Mhz, si deseamos usar la
mxima resolucin r = 10 bits, el ciclo de trabajo mximo posible ser (para M=1):
TPWM = 1024*0.05x10-6 = 0.0128 mseg
O bien, la Frecuencia del PWM definida como FPWM = 1/ PeriodoPWM, tendr un valor
de:
FPWM = 1/0.0128x10-3 = 19.53125 Khz
O de lo contrario la patita CCP1 no podr ser limpiada. Para tener este valor de FPWM se
requiere un valor en PR2 que como ya se dijo, est dado por
PeriodoPWM = (PR2+1)*4*TOSC*M
Despejando:
50

Descripcin Detallada del PIC16F87


PR2= (PeriodoPWM /(4*TOSC*M)) 1,
Sustituyendo, PR2=255 = FFh.
En la siguiente tabla se resumen diversas elecciones de resolucin r y la
correspondiente frecuencia FPWM mxima, as como el valor de PR2 con el que se logra
(para un frecuencia del cristal de 20 Mhz).
FPWM mxima
Preescalador
PR2
Resolucin mxima

1.22 Khz
16
FFh
10

4.88 Khz 19.53 Khz 78.12 Khz 156.3 Khz 208.3 Khz
4
1
1
1
1
FFh
FFh
3Fh
1Fh
17h
10
10
8
7
5.5

3.5.1.3.- Secuencia de configuracin del PWM


A continuacin se resumen los pasos para realizar la configuracin inicial del PWM:
1. Establecer el periodo del PWM escribiendo al registro PR2.
2. Establecer el Ciclo de Trabajo del PWM escribiendo al registro CCPR1L y a los bits
CCP1CON<5:4>.
3. Configurar como salida la patita CCP1, limpiando el bit TRISC<2>.
4. Configurar el preescalador del Timer 2 y habilitar el Timer 2, escribiendo al registro
T2CON.
5. Configurar el mdulo CCP1 para operacin PWM. Poniendo en alto los bits
CCP1CON <2:3>.
A continuacin se ilustra este proceso de configuracin en el siguiente ejemplo.
Ejemplo 18. Control de iluminacin en lazo abierto.
En el siguiente ejemplo se ilustra el uso de la salida PWM para controlar el nivel de
iluminacin producido por una lmpara de acuerdo a la siguiente figura
Vdd

+V

Aumenta
RB0

PIC

Vdd
Disminuye

RB1

RC2/CC
P1

51

Descripcin Detallada del PIC16F87


Eleccin de la frecuencia de operacin del PWM:
Como la carga que se desea controlar es de tipo resistivo, no tendr limitaciones
respecto a frecuencias altas de operacin, salvo las limitaciones de baja frecuencia que
le impone la respuesta trmica para que el parpadeo no sea visible, es decir, se puede
usar desde una frecuencia lenta (del orden de unos 20 hertz) hasta frecuencias tan
altas como el PWM pueda soportar (del orden de los kilohertz).
Para usar los 10 bits de resolucin, repetimos el clculo del ejemplo anterior, pero
ahora supondremos una FOSC = 14.7456 Mhz, es decir, TOSC = 0.06781684 seg,
entonces, el ciclo de trabajo mximo posible ser (para M=1):
TPWM = 1024*0.06781684x10-6 = 0.069444 mseg
O bien, la Frecuencia del PWM definida como FPWM = 1/ PeriodoPWM, tendr un valor
de:
FPWM = 14.4 Khz
Y para lograr esto, se necesita:
PR2= (PeriodoPWM /(4*TOSC*M)) 1,
Sustituyendo, PR2=255 = FFh.
;****************************************************************
;* Este programa controla el ciclo de trabajo de la salida PWM *
;* (patita CCP1) con la cual controlar el nivel de iluminacin *
;* promedio producido por una lmpara controlada con esta seal *
;* Se usa un botn conectado a RB0 para incrementar el nivel y *
;* otro conectado a RB1 para disminuirlo.
*
;* Se supone un cristal de 14.7456 Mhz
*
;****************************************************************
Include "p16f877.inc"
EQU 0x20
EQU 0x21
EQU 0x22
EQU 0x23
org 0x0000
inic BSF STATUS,RP0
;Banco1
BSF TRISB,0
;Configura RB0 como entrada
BSF TRISB,1
;Configura RB1 como entrada
MOVLW 0xFF
;carga periodo
MOVWF PR2
;lo establece para el PWM
BCF TRISC,2
;patita RC2/CCP1 como salida
BCF STATUS,RP0
;Banco 0
CLRF CCPR1L
;inicializa Ciclo de trabajo en cero
BCF CCP1CON,CCP1X
BCF CCP1CON,CCP1Y
MOVLW 0x04
;configura Timer 2
MOVWF T2CON
;preescalador 1/1, habilita Timer 2
BSF CCP1CON,CCP1M3 ;Configura el modulo CCP1 para operacin PWM
BSF CCP1CON,CCP1M2
;en este punto la salida PWM tiene un Ciclo de trabajo CT=0
CLRF CTL
;inicializa CT de 10 bits en cero
CLRF CTH
cont
cont1
CTH
CTL

52

Descripcin Detallada del PIC16F87


Esp0

BTFSC PORTB,0
;Checa Botn RB0
CALL incre
;si est presionado incrementa CT
Esp1 BTFSC PORTB,1
;si no se ha presionado Checa botn RB1
CALL decre
;si est presionado Decrementa CT
MOVF CTL,W
;si no se ha presionado obtiene copia de CT parte baja
MOVWF CCPR1L
;actualiza parte baja del CT real
;**** a continuacin actualiza la parte alta del CT real
MOVLW 0xCF
;mscara
ANDWF CCP1CON,1
;limpia los dos msbits del CT real
MOVLW 0x03
;mscara
ANDWF CTH,1
;limpia los 6 bits altos en CTH
SWAPF CTH,W
;copia los 2 bits bajos de CTH en el nibble alto de W
IORWF CCP1CON,1 ;pone bits que deben ser 1 en los dos msb del CT real
;**** con esto queda actualizada la parte alta del CT real
CALL pau
;pausa para moderar la velocidad de incremento/decremento
GOTO Esp0
;repite
;************************************************************************************
incre INCF CTL,1
;incrementa parte baja de la copia de CT
BTFSS STATUS,Z
;checa si se recicl a cero
RETURN
;si no, retorna
INCF CTH,1
;si se hizo cero incrementa parte alta de CT
RETURN
decre DECF CTL,1
;decrementa parte baja de la copia de CT
COMF CTL,W
;copia negado de CTL a W (para ver si CTL=0xFF)
BTFSS STATUS,Z
;checa si W es cero
RETURN
;si no, retorna
DECF CTH,1
;si s, Decrementa parte alta de CT
RETURN
;** pausa de 50 miliseg. aproximadamente
pau
CLRF cont1
CLRF cont
p1
DECFSZ cont,1
GOTO p1
DECFSZ cont1,1
GOTO p1
RETURN
end

3.5.2.- El Modo Comparador


En el modo de comparacin el registro de 16 bits CCPR1 (CCPR1H:CCPR1L) se
compara constantemente con el valor del registro de 16 bits TMR1. De manera que
cuando sus valores coinciden adems de activarse la bandera para solicitar interrupcin
CCP1IF (PIR1<2>), puede ocurrir en la patita RC2/CCP1 (previa configuracin) alguna
de las siguientes acciones:

RC2/CCP1 Se pone en alto


RC2/CCP1 Se pone en Bajo
RC2/CCP1 no cambia

La accin que ocurra en esta patita se configura mediante los bits de control
CCP1M3:CCP1M0 (CCP1CON<3:0>). En la figura siguiente se muestra un diagrama
de bloques en donde se ilustra la manera en que trabaja el mdulo CCP en modo
comparador

53

Descripcin Detallada del PIC16F87


CCPR1H

CCPR1L

Dispara evento
especial
RC2/CCP1
Lgica
de
salida

Comparador
TMR1H

TMR1L
CCP1CON<3:0>

TRISC<2>

Pone CCP1IF=1

Configuracin del modo de comparacin


A continuacin se hace un resumen de algunas consideraciones que se debern hacer
para configurar adecuadamente el modo de comparacin:

la patita RC2/CCP1 deber configurarse como salida limpiando el bit TRISC<2>.


Al limpiar el registro CCP1CON el latch de salida de la patita RC2/CCP1 se forza
a su valor default de cero.
El Timer 1 debe estar corriendo en modo temporizador (o en modo contador
sincronizado)
Si se est manejando por poleo la bandera de solicitud de interrupcin, se
deber limpiar por software antes de un posible evento que la active, de lo
contrario no se notar la activacin.
El manejo de evento especial no se describe en estos apuntes.

Ejemplo 19.- Generador de Frecuencia Variable.


En este programa se hace uso del modo de comparacin para realizar la conmutacin
de una seal cada vez que transcurre un tiempo, el cual se ajusta al oprimir un botn de
incremento o uno de decremento. El hardware utilizado es similar al del ejemplo
anterior, slo que la salida en lugar de manejar una lmpara, se puede simplemente
monitorear mediante un zumbador piezoelctrico, o visualizarla en un osciloscopio.
;**************************************************************
;* Este programa genera a travs de la patita RC0, una seal *
;* oscilatoria. Se usa un botn conectado a RB0 para incremen-*
;* tar la frecuencia y otro conectado a RB1 para disminuirla. *
;* Se supone un cristal de 14.7456 Mhz
*
;**************************************************************
inic

Include "p16f877.inc"
org 0x0000
BSF STATUS,RP0
;Banco1
BSF TRISB,0
;Configura RB0 como entrada
BSF TRISB,1
;Configura RB1 como entrada
BCF TRISC,2
;patita RC2/CCP1 como salida
BCF STATUS,RP0
;Banco 0
MOVLW 0x01
MOVWF T1CON
;Configura Timer1 modo temporizador, preesc 1/1
CLRF TMR1H
;Inicializa en cero el timer 1
CLRF TMR1L
CLRF CCPR1H
;inicializa periodo de comparacin

54

Descripcin Detallada del PIC16F87


CLRF CCPR1L
;al mnimo (cero)
CLRF CCP1CON
;limpia latch de CCP1
BSF CCP1CON,CCP1M3 ;Habilita modulo CCP1 para modo de comparacin
BCF CCP1CON,CCP1M0 ;Poner salida al coincidir
BCF PIR1,CCP1IF
;limpia bandera de interrupcion.
checa BTFSS PIR1,CCP1IF ;checa bandera
GOTO checa
;si no se ha activado espera
BCF PIR1,CCP1IF
;si ya se activ, la limpia
MOVLW 0x01
;mscara
XORWF CCP1CON,1
;conmuta la accin al coincidir prxima comparacin.
CLRF TMR1L
;limpia la cuenta del timer 1
CLRF TMR1H
BTFSC PORTB,0
;Checa Botn RB0
CALL decre
;si est presionado decrementa periodo
BTFSC PORTB,1
;si no se ha presionado Checa botn RB1
CALL incre
;si est presionado incrementa periodo
GOTO checa
;repite
;************************************************************************************
incre INCF CCPR1L,1
;incrementa parte baja del periodo
BTFSS STATUS,Z
;checa si se recicl a cero
RETURN
;si no, retorna
INCF CCPR1H,1
;si lleg a cero incrementa parte alta del periodo
RETURN
decre DECF CCPR1L,1
;Decrementa parte baja del periodo
COMF CCPR1L,W
;copia negado de CCPR1L a W (para ver si es=0xFF)
BTFSS STATUS,Z
;checa si W es cero
RETURN
;si no, retorna
DECF CCPR1H,1
;si s, Decrementa parte alta del periodo
RETURN
end

3.5.3.- El Modo de Captura


En el modo de captura el registro CCPR1 (CCPR1H:CCPR1L) captura el valor de 16
bits registro TMR1 cuando ocurre un evento en la patita RC2/CCP1. El evento en
cuestin puede especificarse previamente como alguno de los siguientes:

Cada transicin de bajada


Cada transicin de subida
Cada cuarta transicin de subida
Cada dieciseisava transicin de subida

Adems de que el valor de TMR1 es capturado, la bandera de solicitud de interrupcin


CCP1IF es activada, la cual deber ser limpiada por software para poder detectarla si
se est consultando por poleo.
El tipo de accin que se desea detectar en esta patita se configura mediante los bits de
control CCP1M3:CCP1M0 (CCP1CON<3:0>). Si ocurre otro evento de captura antes de
que haya sido ledo el registro CCPR1, el valor capturado anterior se perder, ya que
con la nueva captura este registro es reescrito.
En la figura siguiente se muestra un diagrama de bloques en donde se ilustra la manera
en que trabaja el mdulo CCP en modo de captura

55

Descripcin Detallada del PIC16F87


CCPR1H

CCPR1L

RC2/CCP1
Preescalador
1/1, 1/4,1/16

TMR1H

Detector de
transicin

TMR1L
CCP1CON<3:0>

TRISC<2>
Pone CCP1IF=1

El preescalador del CCP


El valor del preescalador se configura mediante los bits CCP1M3:CCP1M0. Sin
embargo, al realizar un cambio en la configuracin del preescalador se puede generar
una interrupcin falsa, para evitar lo anterior se deber apagar el modulo CCP
(limpiando el registro CCP1CON) previamente al cambio de valor del preescalador.
Este preescalador es independiente al preescalador del Timer 1 (el cual puede usarse
como ya se explic con sus posibles divisores de 1/1, 1/2, 1/4, 18).
Configuracin del modo de captura
A continuacin se hace un resumen de algunas consideraciones que se debern hacer
para configurar adecuadamente el modo de captura:

En el modo de captura la patita RC2/CCP1 deber configurarse como entrada


poniendo en alto el bit TRISC<2>.
Si por alguna razn la patita RC2/CCP1 es configurada como salida, se deber
tener en cuenta que una escritura al puerto C puede causar una condicin de
captura.
El Timer 1 debe estar corriendo en modo temporizador (o en modo contador
sincronizado), de lo contrario el modo de captura puede no funcionar.
Cuando se realiza un cambio de un modo de captura a otro modo de captura se
puede generar una solicitud de interrupcin falsa. Esto debe ser evitado
limpiando la mscara de interrupcin correspondiente (CCP1IE (PIE1<2>))
cuando se realice un cambio de estos para evitar una interrupcin falsa.
Si se est manejando por poleo la bandera de solicitud de interrupcin, se
deber limpiar por software antes de un posible evento que la active, de lo
contrario no se notar la activacin.

Ejemplo 20.- Medicin de Periodo


En este programa se hace uso del modo de captura para realizar la medicin del
periodo de una seal oscilatoria. Para ello se configura el evento de captura para que
ocurra cada vez que la patita RC2/CCP1 detecte una subida en la seal oscilatoria de
entrada. El valor capturado se enva por el puerto serie para su despliegue
56

Descripcin Detallada del PIC16F87


;****************************************************************
;* Este programa mide el periodo de una seal oscilatoria en la *
;* patita RC2/CCP1. El valor de periodo capturado representa el *
;* nmero de ciclos Tcy por periodo y se enva continuamente por*
;* el puerto serie. Se supone un cristal de 14.7456 Mhz
*
;****************************************************************
Include "p16f877.inc"
org 0x0000
msnib EQU 0x20
lsnib EQU 0x21
Inic CALL initrans
;inicializa puerto serie como transmisor
BSF STATUS,RP0
;Banco1
BSF TRISC,2
;patita RC2/CCP1 como entrada
BCF STATUS,RP0
;Banco 0
MOVLW 0x01
MOVWF T1CON
;Configura Timer1 modo temporizador, preesc 1/1
CLRF TMR1H
;Inicializa en cero el timer 1
CLRF TMR1L
;apaga el mdulo CCP para inicializar
CLRF CCP1CON
;limpia latch de CCP1
BSF CCP1CON,CCP1M2 ;Habilita modulo CCP1 para modo de captura
BSF CCP1CON,CCP1M0 ;en transicin de subida
BCF PIR1,CCP1IF
;limpia bandera de interrupcion.
checa BTFSS PIR1,CCP1IF ;checa bandera
GOTO checa
;si no se ha activado espera
BCF PIR1,CCP1IF
;si ya se activ, la limpia
CLRF TMR1L
;limpia la cuenta del timer 1
CLRF TMR1H
MOVF CCPR1H,W
;copia periodo capturado
CALL Envbyte
;y lo enva por el puerto serie
MOVF CCPR1L,W
CALL Envbyte
MOVLW 0x0D
;enva separador
CALL envia
MOVLW 0x0A
CALL enva
GOTO checa
;repite

;***************************************************************
; Subrutina que enva el byte en W por el puerto serie, separado
; en los cdigos ASCII de sus dos nibbles hexadecimales
;***************************************************************
Envbyte:
MOVWF msnib
MOVWF lsnib
SWAPF msnib,1
MOVLW 0x0F
ANDWF msnib,1
ANDWF lsnib,1
MOVF msnib,W
CALL asc
CALL envia
MOVF lsnib,W
CALL asc
CALL envia
RETURN
asc
ADDWF PCL,1

;pone byte en msnib


;y una copia en lsnib
;intercambia nibbles en lsnib
;mscara para limpiar el nibble alto
;limpia parte alta de msnib
;limpia parte alta de lsnib
;carga msnib en W
;obtiene cdigo ASCII equivalente
;lo enva por el puerto serie
;carga lsnib en W
;obtiene cdigo ASCII equivalente
;lo enva por el puerto serie

;Calcula el cdigo a retornar


;Saltando W instrucciones adelante
DT "0123456789ABCDEF"
;****************************************************************
;Subrutina para inicializar el puerto serie USART como transmisor
;a 9600 Bauds, considerando un cristal de reloj de 14.7456 MHZ
;****************************************************************
initrans:
BCF STATUS,RP1
BSF STATUS,RP0
;banco 1
BCF TXSTA,BRGH
;pone bit BRGH=0 (velocidad baja)

57

Descripcin Detallada del PIC16F87


MOVLW 0x17
;valor para 9600 Bauds (Fosc=14.7456 Mhz)
MOVWF SPBRG
;configura 9600 Bauds
BCF TXSTA,SYNC
;limpia bit SYNC (modo asncrono)
BSF TXSTA,TXEN
;pone bit TXEN=1 (habilita transmisin)
BCF STATUS,RP0
;regresa al banco 0
BSF RCSTA,SPEN
;pone bit SPEN=1 (habilita puerto serie)
RETURN
;***************************************************************
;Subrutina para enviar el byte guardado en W por el puerto serie
;***************************************************************
envia BSF STATUS,RP0
;banco 1
esp
BTFSS TXSTA,TRMT
;checa si el buffer de transmisin
GOTO esp
;si est ocupado espera
BCF STATUS,RP0
;regresa al banco 0
MOVWF TXREG
;enva dato guardado en W
RETURN
end

En el ejemplo anterior, el valor del dato (N) de 16 bits desplegado se puede convertir a
segundos (T) de acuerdo a la relacin
T = 4*N/Fosc = (2.712673611*10-7) N seg.
O bien, como frecuencia: F= 1/T= 3,686,400 / N Hertz.

Observacin. El programa debera leer sin problemas periodos entre Tmx= 17.777
mseg (Fmin = 56.25 hertz) y un Tmin=0.271seg (Fmx =3.6864 Mhz), sin embargo
debido al retardo de la rutina de transmisin del dato, (en la realidad el programa no
puede detectar ninguna transicin de subida durante la transmisin del dato) el
programa slo puede procesar correctamente la transicin hasta una frecuencia Fmx
=160Hz (Tmin = 6.25 mseg)

3.5.- Manejo de Interrupciones.


Se le llama interrupcin a un salto especial a una subrutina que no est contemplado en
un punto especfico del programa principal, sino que puede ocurrir en cualquier punto
de ste y no es provocado por una instruccin en el programa, sino por un evento
interno o externo al sistema del microcontrolador.
Los dispositivos que manejan eventos capaces de provocar una solicitud de
interrupcin se denominan fuentes de interrupcin. La familia del PIC16F87x cuenta con
hasta 14 fuentes de interrupcin.
Cada fuente de interrupcin posee dos bits asociados a ella:

Una Bandera (terminada en F) de Interrupcin, la cual es activada (en alto) por el


evento para solicitar una interrupcin.
Una Mscara (terminada en E) Local de Interrupcin, la cual si est desactivada
(en bajo) bloquear la solicitud de interrupcin correspondiente, pero si est
activada (en alto) permitir la solicitud de Interrupcin.
58

Descripcin Detallada del PIC16F87

Adems existe una mscara de interrupcin global GIE (INTCON<7>), la cual


bloquear todas las solicitudes de interrupcin si est desactivada (GIE=0).
Algunas fuentes de interrupcin tambin poseen una segunda mscara de
interrupcin global denominada PEIE (INTCON<6>). De hecho, acta sobre
todas las fuentes de interrupcin, excepto las interrupciones debidas a la patita
INT, el sobreflujo del Timer 0 y las interrupciones del puerto B (INTF, T0IF y
RBIF).

De acuerdo a lo anterior, la nica manera en que una solicitud de interrupcin provoca


en efecto una interrupcin en el programa es cuando:

La mscara global est activada (GIE=1).


(En su caso) la mscara global de perifricos est activada (PEIE=1)
La mscara local est activada
Ocurre un evento que activa la bandera correspondiente.

La lgica de activacin de mscaras y banderas descrita arriba puede entenderse en


trminos de el diagrama lgico mostrado en la siguiente figura. En este diagrama se
muestran las 14 fuentes de interrupcin del PIC16F87x y se usan los nombres
especficos de cada fuente de interrupcin para sus respectivas banderas y mscaras
de interrupcin.
EEIF
EEIE
PSPIF
PSPIE
ADIF
ADIE
RCIF
RCIE
TXIF
TXIE

Despierta si est
en modo SLEEP

T0IF
T0IE
INTF
INTE
RBIF
RBIE

SSPIF
SSPIE
CCP1IF
CCP1IE
TMR2IF
TMR2IE

PEIE
(INTCON<6>)
GIE
(INTCON<7>)

TMR1IF
TMR1IE
CCP2IF
CCP2IE
BCLIF
BCLIE

Proceso de reconocimiento de una interrupcin


Cuando se cumplen las siguientes tres condiciones simultneamente:

59

Interrupcin

Descripcin Detallada del PIC16F87

El bit GIE est activado (en alto)


Se produce un evento que solicita interrupcin (se activa alguna de las banderas
de interrupcin)
Est activada la mscara correspondiente a la bandera acrtivada.

Entonces la CPU es interrumpida inmediatamente y ejecuta lo siguiente:

Termina la ejecucin de la instruccin actual.


Desactiva el bit GIE (GIE=0) para bloquear cualquier otra solicitud de
interrupcin.
La direccin de programa de la siguiente instruccin a ejecutar es guardada en el
stack.
Ejecuta un salto a la localidad de programa 0004h denominada vector de
interrupcin, en donde el usuario deber haber colocado el inicio de la rutina
de atencin a la interrupcin.
Ejecuta la rutina de atencin a la interrupcin escrita por el usuario, en la cual
ste podr constatar la fuente de interrupcin consultando por poleo las
banderas de interrupcin.
La rutina de atencin a la interrupcin deber limpiar los bits de la bandera que
solicit la interrupcin antes de rehabilitar interrupciones, para evitar
interrupciones recursivas.
La rutina de atencin deber terminar con una instruccin RETFIE, la cual activa
nuevamente el bit GIE (GIE=1) y lee el stack para continuar la ejecucin del
programa que fue interrumpido en la siguiente instruccin.

Salvando el contexto durante una interrupcin.


Dado que el programa principal no puede prever en que punto ser interrumpido, la
rutina de atencin a la interrupcin debe ser tal que no altere ninguno de los registros
que requiere paso a paso el programa principal para su operacin normal. Estos
registros son los que van guardando el contexto del programa (tal como en qu banco
est, el resultado de la ltima operacin, etc.) y son:
Registro STATUS
Registro W
Registro PCLATH (si se estn usando las pginas 1, 2 o 3).
El siguiente es un ejemplo del cdigo que deber incluirse al inicio y al final de la rutina
de atencin a la interrupcin para salvar y recuperar el contexto:
;* Salva informacin de contexto previo a la ruitna de atencin a la interrupcin
MOVWF W_Temp
;Salva el registro W en en un registro temporal
SWAPF STATUS,W
;Copia STATUS en W (usa SWAP para no alterarlo al copiarlo)
CLRF STATUS
;Banco cero, sin importar banco actual
MOVWF STATUS_temp ;Salva STATUS en STATUS_temp (Banco 0)
;
MOVF PCLATH,W
;slo se requiere si se estn usando las pginas 1,2,y/o 3
;
MOVWF PCLATH_temp ;salva PCLATH
;
CLRF PCLATH
;pgina 0 sin importar pgina actual
...
;aqu se escribe el cdigo de la rutina de atencin a la interrupcin
...

60

Descripcin Detallada del PIC16F87


;* A continuacin restablece la informacin de contexto que salv al inicio
;
MOVF PCLATH_Temp.,W ;rescata PCLATH
;
MOVWF PCLATH
;si se usan las paginas 1,2 y/o 3
SWAPF STATUS_temp,W ;rescata el STATUS original
MOVWF STATUS
;restablece banco original
SWAPF W_temp,F
;rescata el W original
SWAPF W_temp,W
;sin alterar el STATUS ya rescatado.
RETFIE

Ejemplo 21.- Medidor de periodo mejorado Por Interrupciones.


Como ya se dijo para el ejemplo 20, ste tiene limitantes muy grandes especialmente
en el lmite superior de frecuencia que puede procesar correctamente, debido a que
durante el tiempo empleado en la transmisin del dato no puede detectar ninguna
transicin de la seal de entrada. Esto puede corregirse si la deteccin de la transicin
se realiza mediante interrupciones. La modificacin se muestra en el siguiente listado.
;****************************************************************
;* Este programa mide el periodo de una seal oscilatoria en la *
;* patita RC2/CCP1. Por INTERRUPCIONES generadas por la captura *
;* de cada transicin de 0 a 1 en dicha patita.
*
;* El valor de periodo capturado representa el nmero de ciclos *
;* Tcy por periodo. Dicho valor se enva continuamente por
*
;* el puerto serie. Se supone un cristal de 14.7456 Mhz
*
;****************************************************************
Include "p16f877.inc"
msnib
EQU 0x20
lsnib
EQU 0x21
STATUS_temp EQU 0x70
W_temp
EQU 0x71
org 0x0000
;inicia con un reset
GOTO inic
org 0x0004
;vector de interrupcin
GOTO interr
;salta a la rutina de atencin a la interrupcin
inic CALL initrans
;inicializa puerto serie como transmisor
BSF STATUS,RP0
;Banco1
BSF TRISC,2
;patita RC2/CCP1 como entrada
BCF STATUS,RP0
;Banco 0
MOVLW 0x01
MOVWF T1CON
;Configura Timer1 modo temporizador, preesc 1/1
CLRF TMR1H
;Inicializa en cero el timer 1
CLRF TMR1L
;apaga el mdulo CCP para inicializar
CLRF CCP1CON
;limpia latch de CCP1
BSF CCP1CON,CCP1M2 ;Habilita modulo CCP1 para modo de captura
BSF CCP1CON,CCP1M0 ;en transicin de subida
BCF PIR1,CCP1IF
;limpia bandera de interrupcion.
BSF STATUS,RP0
;banco 1
BSF PIE1,CCP1IE
;Habilita interrupciones del CCP1
BCF STATUS,RP0
;banco 0
BSF INTCON,PEIE
;habilita interrupciones de perifricos
BSF INTCON,GIE
;Habilita interrupciones globales
;** Programa principal:
;** enva continuamente dato de captura al puerto serie
main MOVF CCPR1H,W
;copia periodo capturado
CALL Envbyte
;y lo enva por el puerto serie
MOVF CCPR1L,W
CALL Envbyte
MOVLW 0x0D
;enva separador
CALL envia
MOVLW 0x0A
CALL envia
GOTO main
;repite
;***** rutina de atencin a la interrupcin

61

Descripcin Detallada del PIC16F87


interr
MOVWF W_temp
;salva contexto
SWAPF STATUS,W
CLRF STATUS
MOVWF STATUS_temp
BTFSS PIR1,CCP1IF ;checa bandera de captura de evento
GOTO ret
;si no es bandera de captura retorna
BCF PIR1,CCP1IF
;si es bandera de captura, la limpia
CLRF TMR1L
;limpia la cuenta del timer 1
CLRF TMR1H
ret
SWAPF STATUS_temp,W ;restablece contexto
MOVWF STATUS
SWAPF W_temp,F
SWAPF W_temp,W
RETFIE
;***************************************************************
; Subrutina que enva el byte en W por el puerto serie, separado
; en los cdigos ASCII de sus dos nibbles hexadecimales
;***************************************************************
Envbyte:
MOVWF msnib
;pone byte en msnib
MOVWF lsnib
;y una copia en lsnib
SWAPF msnib,1
;intercambia nibbles en lsnib
MOVLW 0x0F
;mscara para limpiar el nibble alto
ANDWF msnib,1
;limpia parte alta de msnib
ANDWF lsnib,1
;limpia parte alta de lsnib
MOVF msnib,W
;carga msnib en W
CALL asc
;obtiene cdigo ASCII equivalente
CALL envia
;lo enva por el puerto serie
MOVF lsnib,W
;carga lsnib en W
CALL asc
;obtiene cdigo ASCII equivalente
CALL envia
;lo enva por el puerto serie
RETURN
asc
ADDWF PCL,1 ;Calcula el cdigo a retornar
;Saltando W instrucciones adelante
DT "0123456789ABCDEF"
;****************************************************************
;Subrutina para inicializar el puerto serie USART como transmisor
;a 9600 Bauds, considerando un cristal de reloj de 14.7456 MHZ
;****************************************************************
initrans:
BCF STATUS,RP1
BSF STATUS,RP0
;banco 1
BCF TXSTA,BRGH
;pone bit BRGH=0 (velocidad baja)
MOVLW 0x17
;valor para 9600 Bauds (Fosc=14.7456 Mhz)
MOVWF SPBRG
;configura 9600 Bauds
BCF TXSTA,SYNC
;limpia bit SYNC (modo asncrono)
BSF TXSTA,TXEN
;pone bit TXEN=1 (habilita transmisin)
BCF STATUS,RP0
;regresa al banco 0
BSF RCSTA,SPEN
;pone bit SPEN=1 (habilita puerto serie)
RETURN
;***************************************************************
;Subrutina para enviar el byte guardado en W por el puerto serie
;***************************************************************
envia BSF STATUS,RP0
;banco 1
esp
BTFSS TXSTA,TRMT
;checa si el buffer de transmisin
GOTO esp
;si est ocupado espera
BCF STATUS,RP0
;regresa al banco 0
MOVWF TXREG
;enva dato guardado en W
RETURN
end

62

También podría gustarte