Documentos de Académico
Documentos de Profesional
Documentos de Cultura
TMR0
TMR1
TMR2
CCP1 y CCP2
Caractersticas
movlw
movwf
10
TMR0
despus de un tiempo igual a cuatro ciclos de mquina, el contenido del registro comienza a ser
incrementado a 11, 12, 13 y as sucesivamente con una cadencia constante y totalmente
independiente de la ejecucin del resto del programa.
Si, por ejemplo, despus de haber almacenado un valor en el registro TMR0, se ejecuta un bucle
infinito, como se muestra a continuacin:
movlw
movwf
loop
10
TMR0
goto loop
el registro TMR0 es en consecuencia incrementado por el hardware interno del PIC al mismo
tiempo que se ejecuta el bucle.
Una vez alcanzado el valor 255, el registro TMR0 es puesto a cero automticamente reiniciando
entonces el conteo no desde el valor originariamente cargado sino desde cero.
La frecuencia de conteo es directamente proporcional a la frecuencia de reloj aplicada al chip y
puede ser modificada programando adecuadamente algunos bits de configuracin.
En la siguiente figura se muestra un diagrama de bloques de este mdulo:
A continuacin se indican los bits que afectan la operacin del mdulo TMR0 y la manera en
que lo hacen:
La seal Fosc/4 y el pin T0CKI, representan las dos posibles fuentes de seal de reloj,
para el contador TMR0, las cuales se indican cmo se obtienen:
- Fosc/4 es una seal generada internamente por el PIC tomada del circuito de reloj y
que es igual a la frecuencia del oscilador dividida por cuatro.
3
- T0CKI es una seal generada por un posible circuito externo y aplicado al pin
T0CKI.
Las seales T0CS y PSA, son dos conmutadores de seal en cuya salida se presenta una
de las dos seales de entrada en funcin del valor de los bits T0CS y PSA del registro
OPTION.
El bloque Preescalador es un divisor programable cuyo funcionamiento se explicar en
el siguiente subtema.
Para obtener diferentes modalidades de conteo para el registro TMR0, se debe actuar sobre estas
seales y bloques, de las siguientes formas:
1.
Las partes en rojo evidencian el recorrido que efecta la seal antes de llegar al contador
TMR0.
Como se haba ya dicho anteriormente, la frecuencia Fosc/4 es una cuarta parte de la
frecuencia de reloj. Entonces, utilizando un cristal de 4Mhz se tendr una Fosc/4 igual a 1
MHz. Tal frecuencia es enviada directamente al registro TMR0 sin sufrir ningn cambio. La
cadencia de conteo que se obtiene es por lo tanto igual a 1 milln de incrementos por
segundo del valor presente en TMR0.
El modo temporizador se selecciona poniendo a cero el bit T0CS (registro OPTION_REG
<5>). En el modo temporizador, el mdulo Timer0 se incremento en cada cielo de
instruccin (sin el preescaler). Si el registro TMR0 se escribe, el incremento se inhibe
durante los siguientes dos ciclos de instruccin. EL usuario puede trabajar teniendo en
cuenta esto y ajustando el valor a cargar en el TMR0.
En resumen, 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).
4
2. El registro TMR0 como Contador. Ahora se cambia el estado del bit T0CS de 0 a 1,
obtenindose la configuracin mostrada en la siguiente figura.
El modo contador se selecciona poniendo a uno el bit T0CS (registro OPTION_REG <5>).
El modo contador, Timer0 se incremento en cada flaco de subida o de bajada de la seal que
le llega por RA4/TOCK1. El flanco de incremento se determina por el bit T0SE (registro
OPTION_REG <4>). Ponindose a cero T0SE se selecciona el flanco ascendente. Las
restricciones de la seal de reloj externa se describen en la seccin 5.2.
Esta vez ser la seal aplicada al pin TOCKI del PIC la que ser enviada directamente al
contador TMR0, determinando esta la frecuencia de conteo. Por ejemplo, aplicando a este
pin una seal con una frecuencia de 100Hz se obtiene una frecuencia de conteo igual a cien
incrementos por segundo.
La presencia de la compuerta lgica XOR (OR exclusiva) en la entrada TOCKI del PIC,
permite determinar por medio del bit T0SE del registro OPTION si el contador TMR0 debe
ser incrementado en correspondencia con el flanco de bajada (T0SE=1) o con el flanco de
subida (T0SE=0) de la seal externa aplicada.
En la siguiente figura se representa la correspondencia entre el camino de la seal externa y
el valor que toma el contador TMR0 en ambos casos:
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).
6.1.1. Caractersticas del Timer 0
Se analizar la bandera T0IF y el preescalador del Timer0:
a. 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:
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).
La interrupcin de TMR0 se produce cuando el registro TMR0 se desborda al pasar de FFh a
00h. Este desbordamiento pone a uno el bit T0IF (INTCON<2>). La ininterrupcin puede
enmascararse poniendo a cero el bit T0IE (INTCON <5>). EL bit T0IF debe ponerse a cero por
software al finalizar la rutina de atencin a la interrupcin del desbordamiento de TMRO. La
ininterrupcin de TMRO no saca al microcontrolador del estado de SLEEP, debido a que el
temporizador est desactivado durante el modo SLEEP.
b. El preescalador
El ltimo bloque que queda por analizar para poder utilizar completamente el registro TMR0 es
el PRESCALER, el cual determina cmo es posible dividir exteriormente la frecuencia de
conteo, interna externa, activando el PRESCALER.
Si se configura el bit PSA del registro OPTION a 0 se enva al registro TMR0 la seal de salida
del PRESCALER, como se puede ver en la figura 6:
0
0
1
1
0
0
1
1
0
1
0
1
0
1
0
1
Divisor
(timer 0)
1/2
1/4
1/8
1/16
1/32
1/64
1/128
1/256
Divisor
(Watchdog)
1/1
1/2
1/4
1/8
1/16
1/32
1/64
1/128
Nota: Escribir en TMR0, cuando el preescaler es asignado a Timer0, limpia la cuenta del
preescaler, pero no cambia el contenido del preescaler.
6.1.2. Registros del Timer 0
1. Registro OPTION_REG
A manera de resumen se presenta a continuacin una descripcin de los bits del registro
OPTION_REG, que tienen relacin con el Timer 0:
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), 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
bits 2:0 PS2:PS0.- Bits de seleccin del valor del preescaler (ver tabla anterior).
2. Registros asociados al TIMER0
En la siguiente tabla se muestran los registros principales que controlan el comportamiento del
TIMER0 y la distribucin de los bits.
Direccin
Nombre
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Valor en
POR,BOR
Valor en el
resto de Reset
0bh, 8Bh
10Bh,18Bh
INTCON
GIE
PEIE
T0IE
INTE
RBIE
T0IF
INTF
RBIF
0000 000x
0000 000x
81h,181h
OPTION_REG
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
1111 1111
1111 1111
85h
TRISA
---
---
--11 1111
--11 1111
Si T1SYNC se pone a cero, entonces la entrada de reloj externa se sincroniza con los relojes
de fase interiores. La sincronizacin se hace despus de la fase del preescaler. En el
preescaler la fase de la seal de reloj es por lo tanto asncrona.
En este modo de trabajo, durante el modo SLEEP el TIMER1 no se incrementa an cuando
la seal de reloj externa est presente. El preescaler sin embargo contina incrementndose.
2. Modo de funcionamiento del TIMER1 como Contador Asncrono
Cuando el bit de control T1SYNC (T1CON <2>) se poner a uno, la seal de reloj externa no
se sincroniza. El contador sigue realizando la cuenta de forma asncrona respecto a la fase de
la seal de reloj interna. El contador contina la cuenta incluso en el modo SLEEP y puede
generar una interrupcin por desbordamiento que despierta al procesador. Hay que tener
especial cuidado con el software al leer o escribir el contador.
Cuando se trabaja en el modo contador asncrono, el TIMER1 no puede usarse como base de
tiempos para el mdulo CCP (Captura y comparacin-PWM).
Por ltimo, a continuacin se indica los modos del Timer 1, como temporizador y contador,
indicando los bits que afectan su operacin y la manera en que lo hacen:
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>).
Este modo se selecciona poniendo a cero el bit TMR1CS (T1CON <1>. En este modo la
seal de reloj es el reloj interno del microcontrolador FOSC/4. En este modo de trabajo el
bit T1SYNC (T1CON <2>) no tiene ningn efecto ya que el reloj interno est siempre
sincronizado.
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.
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 este modo puede trabajar como contador sncrono o asncrono. Cuando el TIMER1 se
est incrementando segn le llegan los impulsos externos, los incrementos ocurren en los
flancos de subida. Despus de que el TIMER1 se ha configurado como contador, debe
producirse un flanco de bajada antes de empezar a contar.
10
U-0
--Bit 7
U-0
---
R/W-0
TlCKPS1
R/W-0
TlCKPS0
R/W-0
T1OSCEN
R/W-0
#TlSYNC
R/W-0
TMR1CS
R/W-0
TMR1ON
Bit 0
bit 2:
Nombre
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Valor en
POR,BOR
Valor en el
resto de
Reset
INTCON
GIE
PEIE
T0IE
INTE
RBIE
TOIF
INTE
RBIF
0000 000x
0000 000u
PSPIF
PSPIE
ADIF
ADIE
RCIF
RCIE
TXIF
TXIE
SSPIF
SSPIE
CCP1IF
CCP1IE
TMR2IF
TMR2IE
TMR1IF
TMR1IE
0000 0000
0000 0000
0000 0000
0000 0000
PIR1
PIE1
0Eh
TMR1L
0Fh
TMR1H
10h
T1CON
Registro de carga del byte de menor peso del registro de 16 bits de TMR1
---
---
T1CKPS1
T1CKPS0
T1OSCEN
T1SYNC
TMR1CS
TMR1ON
xxxx xxxx
uuuu uuuu
xxxx xxxx
uuuu uuuu
--xx xxxx
--uu uuuu
bit 7:
R/W-0
TOUTPS3
R/W-0
TOUTPS2
R/W-0
TOUTPS1
R/W-0
TOUTPS0
R/W-0
TMR2ON
R/W-0
T2CKPS1
R/W-0
T2CKPS0
Bit 0
bit 6-3: TOUTPS3:TOUTPS0: bit de seleccin del rango del divisor del Postescaler
para el TIMER2
0000 = Divisor del postescaler 1:1
0001 = Divisor del postescaler 1:2
0010 = Divisor del postescaler 1:3
0011 = Divisor del postescaler 1:4
0100 = Divisor del postescaler 1:5
0101 = Divisor del postescaler 1:6
0110 = Divisor del postescaler 1:7
0111 = Divisor del postescaler 1:8
1000 = Divisor del postescaler 1:9
1001 = Divisor del postescaler 1:10
1010 = Divisor del postescaler 1:11
1011 = Divisor del postescaler 1:12
1100 = Divisor del postescaler 1:13
14
bit 1-2: T2CKPS1:T2CKPS0 Seleccin del rango de divisor del Preescaler del TIMER2
00 = Divisor del Preescaler 1:1
01 = Divisor del Preescaler 1:4
1x = Divisor del Preescaler 1:16
Direccin
Nombre
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Valor en
POR,BOR
Valor en
el resto
de Reset
0Bh,8Bh
10Bh,
18Bh
INTCON
GIE
PEIE
TOIE
INTE
TOIF
RBIE
INTE
RBIF
0000 000x
0000 000u
0Ch
PIR1
PSPIF
ADIF
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
0000 0000
0000 0000
0Bh
PIE1
PSPIE
ADIE
RCIE
TXIE
SSPIE
CCP1IE
TMR2IE
TMR1IE
0000 0000
0000 0000
0000 0000
0000 0000
-000 000
-000 0000
1111 1111
1111 1111
11h
12h
92h
TMR2
T2CON
PR2
TOUTPS3
TOUPS2
TOUPS1
TOUPS0
TMR2ON
T2CKPS1
T2CKPS0
Ejemplo 1
Manejo del Timer 0 como contador
El siguiente programa realiza el conteo del 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
ocho transiciones y ser enviado a travs del puerto serie para ser desplegado en la
pantalla de una PC. El reloj de trabajo del microcontrolador es de 4 MHz.
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
INICIO
WTMR0
envbayte
W0x0D
envia
W0x0A
envia
Los diagramas de flujo de las Subrutinas: envbyte, asc, envia e initrans; estn desarrollados en el
Captulo 5 El Convertidor Analgico Digital.
2. Cdigo en Assembler:
;****************************************************************************
;* Este programa realiza el conteo de una seal conectada a la patita T0CKI *
;* el valor del contador lo enva a travs del puerto serie, en 2 bytes
*
;* que representan los nibles (hexadecimal) del TMR0, para su despliegue en *
;* en una PC.
*
;****************************************************************************
Include "p16f877.inc"
org 0x0000
inic
CALL initrans
;inicializa el puerto serie para transmisin
BCF STATUS,RP0
;Banco 0
16
CLRF TMR0
BSF STATUS,RP0
MOVLW 0xE2
MOVWF OPTION_REG
BCF STATUS,RP0
ciclo MOVF TMR0,W
CALL Envbyte
MOVLW 0x0D
CALL envia
MOVLW 0x0A
CALL envia
GOTO ciclo
;***************************************************************
; 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
;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
CALL asc
CALL envia
MOVF lsnib,W
CALL asc
CALL envia
RETURN
asc
;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
ADDWF PCL,1
;****************************************************************
;Subrutina para inicializar el puerto serie USART como transmisor
;a 9600 Bauds, considerando un cristal de reloj de 4 MHZ
;****************************************************************
initrans:
BCF STATUS,RP1
BSF STATUS,RP0
;banco 1
BSF TXSTA,BRGH
;pone bit BRGH=1 (velocidad alta)
MOVLW 0x19
;valor para 9600 Bauds (Fosc=4 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
17
INTEDG
1
T0CS
1
T0SE
0
PSA
0
PS2
0
PS1
1
PS0
0
Bit 0
Bit 7
Bit 0
Almacenar los nibles de TMR0 en msnib y lsnib, como se muestra en los siguientes grficos.
msnib
Bit 7
lsnib
Bit 0
Bit 7
Bit 0
initrans. Subrutina para inicializar el puerto serie USART como transmisor a 9600 Bauds,
Ejemplo 2
Manejo del Timer 0 como temporizador
El siguiente programa utiliza el Timer 0 para realizar una pausa de mxima duracin, con un
reloj de trabajo del microcontrolador de 4 MHz, es pausa 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)
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:
TH = Tciclo = N*M*(4/Fosc)
donde:
N, Cuenta (incrementos)
M, Preescaler (divisor de frecuencia)
Fosc, Reloj del cristal
As, para una duracin mxima M = 256, N = 256 tendremos:
TH = TMAX = 262144/Fosc
Para un reloj de 4 Mhz tendremos
TH = TMAX = 65,536 mseg
F = 1/(2 TH) = 1/(2*65,536 ms)
F = 7,63 Hertz
Y la frecuencia de parpadeo del LED ser F = 7,63 Hertz.
Es decir,
TH = Tciclo = N*M*(4/Fosc)
Fciclo = Fosc/4 * 1/M * 1/N
19
donde:
Fosc/4, Frecuencia de oscilacin (cuenta Timer0)
1/M, Divisor de frecuencia
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
INICIO
RC01
pausa
RC00
pausa
20
pausa
WN1
TMR0W
T0IF=1
NO
SI
T0IF0
FIN
2. Cdigo en Assembler:
;*****************************************************************
;* Este programa hace parpadear un LED conectado a la patita RC0 *
;* Usa el timer 0 para generar una pausa de 65,536 mseg de
*
;* duracin (supone un cristal de 4 Mhz). La frecuencia de
*
;* parpadeo del LED es de 7.63 Hertz aprox.
*
;*****************************************************************
Include "p16f877.inc"
inic
rep
org 0x0000
call iniciatimer0
BSF STATUS,RP0
BCF TRISC,0
BCF STATUS,RP0
BSF PORTC,0
CALL pausa
BCF PORTC,0
CALL pausa
GOTO rep
;Banco1
;patita RC0 como salida
;Banco 0
;enciende LED
;pausa de 65,536 mseg
;apaga LED
;pausa de 65,536 mseg
21
repite
MOVLW N1
MOVWF TMR0
BTFSS INTCON,T0IF
GOTO repite
BCF INTCON,T0IF
RETURN
end
INTEDG
1
T0CS
0
T0SE
0
PSA
0
PS2
1
PS1
1
PS0
1
Bit 0
T0CS = 0, Selecciona el reloj del ciclo de instruccin interno (CLKout) (modo temporizador)
T0SE = 0, No importa
PSA = 0, Asigna el preescalador al Timer0.
PS2=1, PS1=1 y PS0=1; Bits de seleccin del valor del preescaler a 1/256
Programa principal. Este programa enciende LED por un tiempo de 65,536 mseg, luego apaga
donde:
Tciclo, Duracin del ciclo
22
Mz, Nmero cruces por cero o nmero de ciclos del TMR0 (Cuentas del TMR0)
Por ejemplo, un retardo de 1 seg se calcular de la siguiente forma:
N =250 (N1 = 256 250 = 6), 6 ser el valor inicial del TMR0
M = 32
Fosc = 4 MHz
Tciclo = N*M*(4/Fosc)
Tciclo = 250 * 32 * (4/4*106) seg.
= 0,008 seg
tiempo = Tciclo * Mz
Mz = tiempo / Tciclo
= 1 / 0,008
= 125
NOTA. Se debe tener en cuenta que Mz siempre debe ser un valor entero.
El cdigo para la subrutina de 1seg, ser:
;* Subrutina de pausa de 1 seg
;*************************************
Mz
RES 1
N1
EQU 0x06
Delay
;El registro Mz se inicializa a 125 cruces por cero
movlw
125
movwf
Mz
;Lazo de conteo
DelayLoop
movlw
N1
movwf
TMR0
Loop
btfss
goto
bcf
INTCON,T0IF
Loop
INTCON,T0IF
decfsz
goto
Mz,1
DelayLoop
return
Nota: Para un reloj de 4 Mhz, una duracin mxima M = 256, N = 256 se tendr:
Tciclo = N*M*(4/Fosc)
Tciclo = TMAX = 256*256* (4/Fosc)
Tciclo = TMAX = 65,536 mseg
23
Ejemplo Prctico
Realizar un intermitente con cuatro leds cuya frecuencia de intermitencia con un retardo igual a
un segundo utilizando el registro TMR0. El reloj de trabajo del microcontrolador es de 4 MHz.
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
INICIO
Shift0x01
PORTBShift
C0
Shiftrot.izq. Shift
Shift<4>=0
NO
ShiftInter. nibles
SI
Delay
24
Delay
Mz125
TMR0N1
T0IF=1
NO
SI
T0IF0
MzMz-1
NO
Z=1
SI
FIN
2. Cdigo en Assembler:
16F877
DEC
"P16F877.INC"
25
20H
Mz
Shift
RES
RES
1
1
N1
EQU
0x06
26
btfss
goto
bcf
INTCON,T0IF
Loop
INTCON,T0IF
decfsz
goto
Mz,1
DelayLoop
return
END
00000100B
OPTION_REG
En la prctica se debe programar el bit T0CS a 0 para seleccionar como fuente de conteo el reloj
del PIC, el bit PSA a 0 para asignar el PRESCALER al registro TMR0 en lugar de al Watch Dog
Timer (del que trataremos ms adelante) y los bits de configuracin del PRESCALER a 100
para obtener una frecuencia de divisin igual a 1:32. Como se muestra el registro OPTION en la
figura.
RBU
0
INTDEG
0
TOCS=0
PSA=0
PS2=1, PSA1=, PS0=0
T0CS
0
T0SE
0
PSA
0
PS2
1
PS1
0
PS0
0
La subrutina Delay deber utilizar el registro TMR0 para obtener un retardo igual a un segundo.
Entonces, las primeras instrucciones que se escribe en Delay son:
movlw
movwf
125
Mz
movlw
movwf
N1
TMR0
Las segundas dos almacenan en TMR0 el valor N1=6 de modo que el registro TMR0 alcanza el
cero despus de 250 cuentas (256 - 6 = 250), obteniendo as una frecuencia de paso por cero
del TMR0 igual a:
31.250 / 250 = 125 Hz
Las instrucciones siguientes almacenan en un registro de 8 bits (Count) el valor 125, de tal modo
que, decrementando este registro en uno por cada paso por cero de TMR0, se obtenga una
frecuencia de pasos por cero del registro Count igual a:
125/125 = 1Hz
Las instrucciones insertadas en el bucle DelayLoop se ocupan por lo tanto de controlar si TMR0
ha alcanzado el cero, luego de reinicializarlo a 6 y decrementar el valor contenido en Count.
Cuando Count alcance tambin el valor cero, entonces habr trascurrido un segundo y la
subrutina podr retornar control al programa que la llam.
Ejemplo 3
Manejo del Timer 1 como temporizador
A continuacin se describe un programa similar al Ejemplo 2 , en el que se utiliza el Timer
1 para realizar una pausa de mxima duracin, co n u n reloj de trabajo del
microcontrolador de 4 MHz, la pausa 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)
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)
28
RC01
pausa1
RC00
pausa1
29
pausa1
WN1
TMR1HW
WN0
TMR1LW
TMR1IF=1
NO
SI
TMR1IF0
FIN
2. Cdigo en Assembler:
;*****************************************************************
;* Este programa hace parpadear un LED conectado a la patita RC0 *
;* Usa el timer 1 para generar una pausa de 524,288. mseg de
*
;* duracin (supone un cristal de 4 Mhz). La frecuencia de
*
;* parpadeo del LED es de 0,95367 Hertz aprox.
*
;*****************************************************************
Include "p16f877.inc"
org 0x0000
call iniciatimer1
inic
BSF STATUS,RP0
BCF TRISC,0
BCF STATUS,RP0
;Banco1
;patita RC0 como salida
;Banco 0
rep
BSF PORTC,0
CALL pausa1
BCF PORTC,0
CALL pausa1
GOTO rep
;enciende LED
;pausa de 524,288 mseg
;apaga LED
;pausa de 524,288 mseg
30
MOVLW 0x31
MOVWF T1CON
return
end
--0
T1CKPS1
1
T1CKPS0
1
T1OSCEN
0
T1SYNC
0
TMR1CS
0
TMR1ON
1
Bit 0
El programa es idntico al Ejemplo 2, lo nico que cambia son las subrutinas de iniciatimer1 y
pausa1, las cuales ahora se han realizado con el Timer 1 y no con el Timer 0.
Programa principal. Este programa enciende LED por un tiempo de 524,288 mseg, luego apaga
es decir:
N1:N0 = 65536 - N
Por ejemplo, utilizando el Timer1 obtener un Delay de 1.5 seg, con una frecuencia de
oscilacin de 4 MHz.
Primero se calcula el Tciclo mximo con los siguientes valores:
N = 65536; es el mximo valor que alcanza con FFFF
M = 8; es el valor mximo del preescalador en el timer1 de 1/8
Fosc = 4MHz
T = Tciclo = N*M*(4 / Fosc)
Tciclomax = 65536*8* (4 / 4MHz)
Tciclomax = 0.524288 seg
Luego, se debe calcular el nmero de cruces por cero Mz, porque no alcanza Tciclomax = 524,288
mseg a los 1.5 seg, mediante la siguiente ecuacin:
tiempo = Tciclo * Mz
Mz = tiempo / Tciclo
Mz = 1,5 seg / 0.524288 seg
Mz = 2,86102
Pero Mz no es entero, por lo que se debe hacer un nuevo clculo con un nuevo Tciclo, en donde:
tiempo = 1.5 seg
Tciclo = 12 mseg (se escoge cualquier valor entero mltiplo de M*N y mucho menor a
Tciclomax = 0.524288 seg)
Mz = 1,5 seg / 0,012 seg
Mz = 125
Mz = 0x7D
Ahora se debe calcular N y M en base al Tciclo:
N1:N0 = 65536 N
N1:N0 = 65536 1500 = 64036
N1:N0 = 0x FA24
Entonces, TMR1H y TMR1L ser:
N1 = TMR1H = 0xFA
N0 = TMR1L = 0x24
;********************************************************
;*
Subrutina Delay1,5s
*
;* Usa el Timer1 para obtener un Delay
*
;* de 1.5 seg, con fosc = 4MHz.
*
;********************************************************
N1
EQU 0xFA
N0
EQU 0x24
Mz
EQU 0x7D
Delay15s
MOVLW N1
MOVWF TMR1H
MOVLW N0
MOVWF TMR1L
BCF PIR1,TMR1IF
MOVLW 0x31
MOVWF T1CON
BTFSS PIR1,TMR1IF
GOTO ciclo
decfsz Mz,1
goto Delay15s
ciclo
return
Ejemplo 4
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 2 y 3 de dejar pasar el tiempo transcurrido en una sola activacin
de TMR2IF?. El reloj de trabajo del microcontrolador es de 4 MHz.
Solucin.
Sea Tciclo 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, se tiene que la duracin de la
pausa dada es:
Tciclo = N*M*P*(4/Fosc)
As, para una duracin mxima P = M = 16, N = 256 (N=PR2) se tendr:
TcicloMAX = 262144/Fosc
33
RC01
pausa2
RC00
pausa2
34
pausa2
WN3
PR2W
TMR2IF=1
NO
SI
TMR2IF0
FIN
2. Cdigo en Assembler:
;*****************************************************************
;* Este programa hace parpadear un LED conectado a la patita RC0 *
;* Usa el timer 2 para generar una pausa de 65,536. mseg de
*
;* duracin (supone un cristal de 4 Mhz). La frecuencia de
*
;* parpadeo del LED es de 7,63 Hertz aprox.
*
;*****************************************************************
Include "p16f877.inc"
org 0x0000
call iniciatimer2
inic
BSF STATUS,RP0
BCF TRISC,0
BCF STATUS,RP0
;Banco1
;patita RC0 como salida
;Banco 0
rep
BSF PORTC,0
CALL pausa2
BCF PORTC,0
CALL pausa2
GOTO rep
;enciende LED
;pausa de 65,536 mseg
;apaga LED
;pausa de 65,536 mseg
35
MOVLW N
BSF STATUS,RP0
MOVWF PR2
BCF STATUS,RP0
repite BTFSS PIR1,TMR2IF
GOTO repite
BCF PIR1,TMR2IF
RETURN
end
TOUTPS3
1
TOUTPS2
1
TOUTPS1
1
TOUTPS0
1
TMR2ON
1
T2CKPS1
1
T2CKPS0
1
Bit 0
El programa es idntico al Ejemplo 2, lo nico que cambia son las subrutinas de iniciatimer2 y
pausa2, las cuales ahora se han realizado con el Timer 2 y no con el Timer 0.
Programa principal. Este programa enciende LED por un tiempo de 65,536 mseg, luego apaga
36
Recurso
utilizado
Captura
Comparacin
PWM
Timer 1
Timer 1
Timer 2
37
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 4 transiciones de subida
Captura cada 16 transiciones de subida
Comparacin, pone salida cada coincidencia (Pone 1 a la salida)
Comparacin, limpia salida cada coincidencia (Pone 0 a la salida)
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.
2. Interaccin de los dos mdulos CCP
Modo CCPx
Captura
Captura
Modo CCPy
Captura
Comparacin
Comparacin
Comparacin
PWM
PWM
PWM
PWM
Captura
Comparacin
Interacin
La misma base de tiempos de TMR1
El comparador debe configurarse para el modo de
disparo especial que pone a cero el TMR1
El Comparador(es) debe configurarse para el modo de
disparo especial que pone a cero el TMR1
El PWM tendr la misma frecuencia y proporcin de
actuacin (interrupcin de TMR2)
Ninguna
Ninguna
U-0
---
R/W-0
CCPxX
R/W-0
CCPxY
R/W-0
CCPxM3
R/W-0
CCPxM2
R/W-0
CCPxM1
R/W-0
CCPxM0
Bit 0
bit 3-0:CCPxM3-.CCPxM0; bit de seleccin del modo de trabajo del mdulo comparador
CCPX.
CCPxM3:
CCPxM0
0000
0100
0101
0110
0111
1000
1001
1010
1011
11xx
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.
39
Nota 1: los 8 bits del registro TMR2 son concatenados con 2 bits del preescalador para crear
una base de tiempo de 10 bits.
A continuacin se explica el Control del Periodo del PWM y el Control del Ciclo de Trabajo del
PWM:
a. 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.
b. Control del Ciclo de Trabajo del PWM
El ciclo de Trabajo se especifica escribiendo un valor de 10 bits al registro CCPR1L (los 8
40
bits ms significativos (msb)) y los dos bits menos significativos (lsb) a CCP1CON<5:4>
este valor de 10 bits lo representaremos como 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
donde, TPWM es el valor de la duracin del ciclo de trabajo (CT)
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 CCP1CON<5:4>) alcanza el
valor de CCPR1H (concatenado con dos bits del preescalador) la patita CCP1 es
limpiada (ver figura anterior).
Como puede ver, 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:
T
= (2 r)* T *M
PWM
OSC
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
Por ejemplo, suponiendo un cristal de 20 Mhz, si s e desea usar la mxima resolucin r
= 10 bits, el ciclo de trabajo mximo posible ser (para M=1):
TPWM = 1024*0,05x10-6 = 0,0512 mseg (CT Mxima)
O de lo contrario la patita CCP1 no podr ser limpiada.
Para tener este valor de PeriodoPWM se requiere un valor en PR2 que como ya se dijo, est dado
41
por:
PeriodoPWM = (PR2+1)*4*TOSC*M
Despejando PR2 ser:
PR2= (PeriodoPWM / (4*TOSC*M)) 1
Pero si se desea tener el PeriodoPWM mximo se sustituye, PR2=255 = FFh (valor mximo) y
M=1:
PeriodoPWM = (255+1)*4*0,05x10-6 *1
= 0,0512 mseg
O bien, la Frecuencia del PWM mxima definida como FPWM = 1/ PeriodoPWM, tendr un
valor de:
FPWM = 1/0,0512x10-3 = 19,53125 Khz
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
una frecuencia del cristal de 20 Mhz).
FPWM mxima
1.22 Khz
4.88 Khz
19.53 Khz
78.12 Khz
156.3 Khz
208.3 Khz
Preescalador
PR2
Resolucin
mxima
16
FFh
4
FFh
1
FFh
1
3Fh
1
1Fh
1
17h
10
10
10
5.5
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
45
Ejemplo 5
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:
TPWM
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
INICIO
CTL0
CTH0
RB0=0
NO
incre
SI
RB1=0
NO
decre
SI
CCPR1LCTH
W0xCF
CCP1CONCCP1CON AND W
W0x03
Mscara
Mscara
CTHCTL AND W
CCP1CONCCP1CON OR W
47
incre
d20ms
CTLCTL+1
W0x04
WW-CTL
NO
Z=1
SI
CTL0
CTHCTH+1
FIN
48
49
2. Cdigo en Assembler:
;****************************************************************
;* 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 4 Mhz
*
;****************************************************************
include "p16f877.inc"
;Define constantes
N
EQU 0x1A
M
EQU 0x0
cont1 EQU 0x20
cont2 EQU 0x21
CTH
CTL
EQU 0x22
EQU 0x23
;Banco1
;Configura RB0 como entrada
;Configura RB1 como entrada
;carga periodo
;lo establece para el PWM (PR2 = 255)
50
BCF TRISC,2
BCF STATUS,RP0
CLRF CCPR1L
BCF CCP1CON,CCP1X
BCF CCP1CON,CCP1Y
MOVLW 0x04
MOVWF T2CON
BSF CCP1CON,CCP1M3
BSF CCP1CON,CCP1M2
Botn RB0
;si est presionado incrementa CT
;si no se ha presionado Checa botn RB1
;si est presionado Decrementa CT
MOVF CTH,W
MOVWF CCPR1L
;****
MOVLW
ANDWF
MOVLW
ANDWF
SWAPF
IORWF
;****
GOTO Esp0
;repite
;************************************************************************************
;**incrementa parte baja y alta de la copia de CT
incre
CALL d20ms
;pausa para eliminar rebores
INCF CTL,1
;incrementa parte baja de la copia de CT
MOVLW 0X04
SUBWF CTL,W
;resta 4 menos CTL
BTFSS STATUS,Z
;checa si se llega a 4 la parte baja, cuenta mxima 3
RETURN
;si no, retorna
CLRF CTL
INCF CTH,1
;si se llego a 4 la parte baja, incrementa parte alta de CT
RETURN
;**decrementa parte baja y alta de la copia de CT
decre
CALL d20ms
;pausa para eliminar rebores
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),
;para ver el valor 11111111
BTFSS STATUS,Z
;checa si W es cero
RETURN
;si no, retorna
MOVLW 0X03
MOVWF CTL
DECF CTH,1
;si s, decrementa parte alta de CT
RETURN
;**Subrutina de pausa 20 mseg para reloj 4 MHz
d20ms 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
51
GOTO rep1
RETURN
esc
END
0
Bit 7
0
Bit 0
El registro CCPR1L es el registro que pasa a ser la parte ms significativa del ciclo PWM, que comienza
con el valor 0.
Registro CCP1CON
---
---
CCP1X
0
CCP1Y
0
CCP1M3
1
CCP1M2
1
CCP1M1
0
Bit 7
CCP1M0
0
Bit 0
Los bits CCP1X y CCP1Y de CCP1CON<5:4>, son los bits menos significativos del ciclo PWM, que
comienzan con el valor 0.
CCP1X = 0,
CCP1Y = 0,
Configura el Mdulo CCP1 para operacin PWM
CCP1M3=1
CCP1M2=1
CCP1M1=0
CCP1M0=0
Registro T2CON
T2CON = 0x04
--0
Bit 7
T2OUPS3
0
T2OUPS2
0
T2OUPS1
0
T2OUPS0
0
TMR20N
1
T2CKPS1
0
T2CKPS0
0
Bit 0
T2CKPS1=0
T2CKPS0=0
Programa principal. Este programa comienza la salida PWM con un ciclo de trabajo CT=0
(CTH:CTL), inicializa CT de 10 bits en cero. Luego checa Botn RB0; si est presionado
incrementa CT, si no se ha presionado chequea botn RB1; si est presionado decrementa CT.
Luego actualiza parte alta de CT real y a continuacin realiza el proceso que actualiza la parte
baja del CT real.
Para la actualizacin de la parte baja del CT real, se realiza las siguientes tareas:
Limpia los dos bits menos significativos del CT real en CCP1CON=UU00XXVV, con la
mscara 11001111 (0xCF),
MOVLW 0xCF
ANDWF CCP1CON,1
;mscara
;limpia los dos lsbits del CT real
Limpia los seis bits altos en CTL=000000YY, con la mscara 00000011 (0x03),
MOVLW 0x03
ANDWF CTL,1
;mscara
;limpia los 6 bits altos en CTL
;pone bits que deben ser los dos lsb del CT real
;repite
53
Ejemplo 6
Generador de Frecuencia Variable.
En este programa se usa el 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, con un cristal de 4 Mhz
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
54
CCPR1LCCPR1L+1
NO
Z=1
SI
CCPR1HCCPR1H+1
FIN
CCPR1LCCPR1L-1
WCOMP CCPR1L
NO
Z=1
SI
CCPR1HCCPR1H-1
FIN
55
BSF STATUS,RP0
BSF TRISB,0
BSF TRISB,1
BCF TRISC,2
BCF STATUS,RP0
MOVLW 0x01
MOVWF T1CON
;Banco1
;Configura RB0 como entrada
;Configura RB1 como entrada
;patita RC2/CCP1 como salida
;Banco 0
CLRF TMR1H
CLRF TMR1L
CLRF CCPR1H
CLRF CCPR1L
CLRF CCP1CON
;limpia latch de CCP1
BSF CCP1CON,CCP1M3 ;Habilita modulo CCP1 para modo de comparacin
BCF CCP1CON,CCP1M0 ;pone salida en 1 al coincidir
BCF PIR1,CCP1IF
;limpia bandera de interrupcin.
checa BTFSS PIR1,CCP1IF
GOTO checa
BCF PIR1,CCP1IF
MOVLW 0x01
XORWF CCP1CON,1
CLRF TMR1L
CLRF TMR1H
Esp1
BTFSC PORTB,0
GOTO RB0_1
BTFSC PORTB,1
GOTO RB1_1
GOTO checa
;repite
;******************
;**acciones del men
RB0_1
CALL d20ms
CALL incre
GOTO Esp1
RB1_1
CALL d20ms
CALL decre
GOTO checa
;******************
;************************************************************************************
;**Inncrementa parte baja y alta del periodo
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
56
--0
Bit 7
--0
T1CKPS1
0
T1CKPS0
0
T1OSCEN
0
T1SYNC
0
TMR1CS
0
TMR1ON
1
Bit 0
CCP1M3
1
CCP1M2
0
CCP1M1
0
CCP1M0
0
Bit 0
---
CCP1X
0
CCP1Y
0
Bit 7
Los bits CCP1X y CCP1Y de CCP1CON<5:4>, no importan.
Configura el Mdulo CCP1 para operacin Comparacin con salida 1.
CCP1M3=1
CCP1M2=0
CCP1M1=0
CCP1M0=0
Luego, configura el Mdulo CCP1 para operacin Comparacin con salida 0.
57
CCP1M3=1
CCP1M2=0
CCP1M1=0
CCP1M0=1
Programa principal. Este programa genera a travs de la patita RC2, una seal oscilatoria. Se usa un
botn conectado a RB0 para incrementar el periodo y otro conectado a RB1 para disminuirlo,
como se muestra en la siguiente figura:
Se comienza inicializando el periodo de comparacin al mnimo (cero), limpia latch de CCP1, habilita
mdulo CCP1 para modo de comparacin; poniendo la salida en 1 al coincidir los valores, y limpia
bandera de interrupcin,
CLRF CCPR1H
;inicializa periodo de comparacin
CLRF CCPR1L
;al mnimo (cero)
CLRF CCP1CON
;limpia latch de CCP1
BSF CCP1CON,CCP1M3 ;Habilita modulo CCP1 para modo de comparacin
BCF CCP1CON,CCP1M0 ;pone salida en 1 al coincidir
BCF PIR1,CCP1IF
;limpia bandera de interrupcin.
---
CCP1X
0
CCP1Y
0
CCP1M3
1
CCP1M2
0
CCP1M1
0
Bit 7
CCP1M0
0
Bit 0
configurado el Mdulo CCP1 para modo comparacin, se pone a la patilla RC2/CCP1 a 1 al coincidir los
valores (el bit CCP1IF se pone en 1)
CCP1M3=1
CCP1M2=0
CCP1M1=0
CCP1M0=0
Checa bandera (lazo de espera); si no se ha activado espera, si ya se activ la limpia.
checa BTFSS PIR1,CCP1IF
GOTO checa
BCF PIR1,CCP1IF
;mscara
;conmuta la accin al coincidir prxima comparacin.
58
---
CCP1X
0
CCP1Y
0
CCP1M3
1
Bit 7
CCP1M2
0
CCP1M1
0
CCP1M0
1
Bit 0
configurado el Mdulo CCP1 para modo comparacin, se pone a la patilla RC2/CCP1 a 0 al coincidir los
valores (el bit CCP1IF se pone en 1),
CCP1M3=1
CCP1M2=0
CCP1M1=0
CCP1M0=1
A continuacin limpia la cuenta del timer 1 y checa botn RB0; si est presionado incrementa el
periodo, si no se ha presionado checa botn RB1; si est presionado decrementa el periodo.
Repitiendo todo nuevamente,
GOTO checa
;repite
59
Ejemplo 7
Medicin de Periodo
En este programa usa el 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.
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
60
INICIO
CCPIF0
CCPIF=1
NO
SI
CCPIF0
TMR1L0
TMR1H0
envbayte
envbayte
W0x0D
envia
W0x0A
envia
Los diagramas de flujo de las Subrutinas: envbyte, asc, envia e initrans; estn desarrollados en el
Captulo 5 El Convertidor Analgico Digital.
2. Cdigo en Assembler:
61
;****************************************************************
;* 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 4 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
;
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
;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
;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
;****************************************************************
;Subrutina para inicializar el puerto serie USART como transmisor
;a 9600 Bauds, considerando un cristal de reloj de 4 MHZ
62
;****************************************************************
initrans:
BCF STATUS,RP1
BSF STATUS,RP0
;banco 1
BSF TXSTA,BRGH
;pone bit BRGH=1 (velocidad alta)
MOVLW 0x19
;valor para 9600 Bauds (Fosc=4 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, con un reloj de 4MHz:
T = 4*N/Fosc M = (1*10-6) N M seg.
O bien, como frecuencia: F= 1/T= 1 / N M Hertz.
Observacin
El programa debera leer sin problemas periodos entre Tmx= 65,536 mseg (Fmin = 15,2587
Hz) y un Tmin=1seg (Fmx = 1 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).
Anlisis del cdigo
En primer lugar configuramos el registro T1CON y CCP1CON.
Registro T1CON
T1CON=0x01
--0
Bit 7
--0
T1CKPS1
0
T1CKPS0
0
T1OSCEN
0
T1SYNC
0
TMR1CS
0
TMR1ON
1
Bit 0
---
CCP1X
0
CCP1Y
0
CCP1M3
0
CCP1M2
1
CCP1M1
0
Bit 7
CCP1M0
1
Bit 0
Configurado el Mdulo CCP1 para modo captura por flanco ascendente en RC2/CCP1, como se muestra
en la siguiente figura:
CCP1M3=0
CCP1M2=1
CCP1M1=0
CCP1M0=1
Programa principal. 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.
Checa bandera; si no se ha activado espera, si ya se activ la limpia, a continuacin limpia la
cuenta del timer 1, copia la cuenta del Timer 1 capturado y lo enva por el puerto serie, luego
enva 0x0D y 0x0A.
Repitiendo todo nuevamente,
GOTO checa
;repite
envbyte, subrutina que enva el byte en W por el puerto serie, separado en los cdigos ASCII de
sus dos nibbles hexadecimales.
initrans, subrutina para inicializar el puerto serie USART como transmisor a 9600 Bauds,
considerando un cristal de reloj de 4 MHZ.
envia, subrutina para enviar el byte guardado en W por el puerto serie.
64