6 El Módulo Temporizador PIC

48
1 El Módulo Temporizador

description

El Módulo Temporizador PIC

Transcript of 6 El Módulo Temporizador PIC

Page 1: 6 El Módulo Temporizador PIC

1

El Módulo Temporizador

Page 2: 6 El Módulo Temporizador PIC

2

1. Descripción General del Módulo Temporizador (Timer)

Los PIC 16F87X poseen un módulo para el manejo preciso y eficiente de operaciones que

involucran tiempo o conteo. Este módulo consta de:

• Tres contadores/temporizadores denominados TMR0, TMR1 y TMR2

• Dos módulos CCP (Captura, Comparación y PWM (Modulación de ancho de

pulso) denominados CCP1 y CCP2

En la siguiente tabla se resumen las principales características de los módulos

mencionados:

Módulo Características

TMR0

� TMR0 es un Contador/Temporizador de 8 bits

� Leíble y escribible

� Reloj interno o externo

� Selección de flanco activo en el reloj externo

� Preescalador de 8 bits programable

� Solicitud de interrupción opcional en el desbordamiento (de

FFh a 00h)

TMR1

� TMR1 es un Contador/Temporizador de 16 bits

� Leíble y escribible

� Reloj interno o externo

� Preescalador programable

� Solicitud de interrupción opcional en el desbordamiento (de

FFFFh a 0000h)

� Reinicialización opcional desde los módulos CCP

TMR2

� TMR2 es un Temporizador de 8 bits

� Dispone de un registro de periodo de 8 bits (PR2)

� Leíble y escribible

� Preescalador programable

� Postescalador programable

� Solicitud de interrupción opcional al coincidir TMR2 y PR2

� Posibilidad de generar impulsos al módulo SSP (puerto serie

síncrono)

CCP1 y CCP2 � Modo de captura

� Modo de comparación

� Modo PWM (modulación de ancho de pulso)

1.1. El Módulo del Timer 0

El Timer 0 es un contador/temporizador de 8 bits. El registro principal de este módulo 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 señal externa (modo contador).

El registro TMR0 es un contador, es decir un tipo de registro particular cuyo contenido es

incrementado con una cadencia regular y programable directamente por el hardware del PIC. En

la práctica, a diferencia de los otros registros, el TMR0 no mantiene inalterado el valor que tiene

almacenado, sino que lo incrementa continuamente, si por ejemplo se escribe en él el valor 10

con las siguientes instrucciones:

Page 3: 6 El Módulo Temporizador PIC

3

movlw 10 movwf TMR0

después de un tiempo igual a cuatro ciclos de máquina, el contenido del registro comienza a ser

incrementado a 11, 12, 13 y así sucesivamente con una cadencia constante y totalmente

independiente de la ejecución del resto del programa.

Si, por ejemplo, después de haber almacenado un valor en el registro TMR0, se ejecuta un bucle

infinito, como se muestra a continuación:

movlw 10 movwf TMR0 loop 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 automáticamente 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 configuración.

En la siguiente figura se muestra un diagrama de bloques de este módulo, en donde se indican

los bits que afectan su operación y la manera en que lo hacen.

• La señal Fosc/4 y el pin T0CKI, representan las dos posibles fuentes de señal de reloj,

para el contador TMR0.

- Fosc/4 es una señal generada internamente por el PIC tomada del circuito de reloj y

que es igual a la frecuencia del oscilador dividida por cuatro.

- T0CKI es una señal generada por un posible circuito externo y aplicado al pin

T0CKI.

Page 4: 6 El Módulo Temporizador PIC

4

• Las señales T0CS y PSA, son dos conmutadores de señal en cuya salida se presenta una

de las dos señales de entrada en función 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

señales y bloques, de las siguientes formas.

1. El registro TMR0 como Temporizador. Se programa el bit T0CS a 0 y PSA a 1,

obteniéndose la configuración de funcionamiento la que se representada en la siguiente

figura.

Las partes en rojo evidencian el recorrido que efectúa la señal antes de llegar al contador

TMR0.

Como se había 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 ningún cambio. La

cadencia de conteo que se obtiene es por lo tanto igual a 1 millón 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 módulo Timer0 se incremento en cada cielo de

instrucción (sin el preescaler). Si el registro TMR0 se escribe, el incremento se inhibe

durante los siguientes dos ciclos de instrucción. EL usuario puede trabajar teniendo en

cuenta esto y ajustando el valor a cargar en el TMR0.

En resumen, en el modo temporizador la señal 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 instrucción (Tcy).

2. El registro TMR0 como Contador. Ahora se cambia el estado del bit T0CS de 0 a 1,

obteniéndose la configuración mostrada en la siguiente figura.

Page 5: 6 El Módulo Temporizador PIC

5

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 señal que

le llega por RA4/TOCK1. El flanco de incremento se determina por el bit T0SE (registro

OPTION_REG <4>). Poniéndose a cero T0SE se selecciona el flanco ascendente. Las

restricciones de la señal de reloj externa se describen en la sección 5.2.

Esta vez será la señal 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 señal con una frecuencia de 100Hz se obtiene una frecuencia de conteo igual a cien

incrementos por segundo.

La presencia de la compuerta lógica 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 señal externa aplicada.

En la siguiente figura se representa la correspondencia entre el camino de la señal externa y

el valor que toma el contador TMR0 en ambos casos:

Cuando no se utiliza el preescaler, la entrada de reloj externa es igual a la salida del

preescaler. Las sincronización de TOCKI con los relojes de fase interior se acopla, a la

salida del preescaler en los ciclos Q2 y Q4 de los relojes de fase internos. Por

consiguiente, es necesario que TOCKI está a nivel alto por al menos durante 2Tosc (y un

pequeño retardo de 20ns) y a nivel bajo por lo menos 2Tosc (y un retardo RC de 20ns).Ver

las características eléctricas del dispositivo deseado.

En resumen, en el modo contador, la señal que controla los incrementos del registro

TMR0 es una señal 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 transición que provoca los incrementos mediante el bit “Timer0 Source

Edge Select“ T0SE (OPTION_REG<4>), limpiando este bit se selecciona la

transición de subida, mientras que al ponerlo en alto se selecciona la de bajada.

Page 6: 6 El Módulo Temporizador PIC

6

Observación: En este modo, la señal 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 más un pequeño retardo de 20nseg y lo mismo en bajo. (es decir, señales demasiado

estrechas (rápidas) no podrán ser detectadas).

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>) poniéndose en 1. Esta

activación puede usarse de dos maneras:

• Para solicitar una interrupción

• Para ser consultada por poleo

En ambos casos debe tenerse en cuenta que para poder detectar una activación (un 1) en esta

bandera, previamente habrá que limpiarla por software. Esto debe realizarse en la inicialización

del Timer y después de que un reciclo la ha activado. Lo último puede hacerse en la rutina de

atención a la interrupción, o bien, en la rutina que la consulta por poleo (según sea el caso).

La interrupción 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 ininterrupción puede

enmascararse poniendo a cero el bit T0IE (INTCON <5>). EL bit T0IF debe ponerse a cero por

software al finalizar la rutina de atención a la interrupción del desbordamiento de TMRO. La

ininterrupción 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 cómo 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 envía al registro TMR0 la señal de salida

del PRESCALER, como se puede ver en la figura 6:

Page 7: 6 El Módulo Temporizador PIC

7

El PRESCALER consiste en la práctica, en un divisor programable de 8 bits a utilizar en el caso

de que la frecuencia de conteo enviada al contador TMR0 sea demasiado elevada para propósitos

de cualquier aplicación.

Hay sólo un preescaler disponible que está compartido y puede asignarse indistintamente al

moduló de Timerl y el al WDT. La asignación del preescaler al Timer0 hace que no haya

ningún preescaler para el WDT, y viceversa. Este preescaler no se puede leer ni escribir.

El bit PSA y PS2:PS0 (OPTION_REG <3:0>) determinan la asignación del preescaler y el

rango del preescaler. Cuando se le asigna al módulo del Tirner0, todas las instrucciones, que

escriben en el registro TMR0 (por ejemplo CLRF TMR0, MOVWF TMR0, BSF TMR0,x...

etc.) ponen a cero el preescaler. Cuando se le asigna al WDT, una instrucción CLRWDT limpia

el preescaler junto con el temporizador del WDT. EL preescaler no se puede leer ni escribir.

Nota.- Escribir en TMR0, cuando el preescaler es asignado a Timer0, limpia la cuenta del

preescaler, pero no cambia el contenido del preescaler.

Es decir, el preescalador es un divisor de frecuencia de módulo seleccionable. Como se puede

ver en la figura anterior, el preescalador está compartido entre el timer0 y el módulo

watchdog, sin embargo sólo 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 selección del módulo (valor de división 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 Divisor

(timer 0) Divisor

(Watchdog)

0 0 0 1/2 1/1

0 0 1 1/4 1/2

0 1 0 1/8 1/4

0 1 1 1/16 1/8

1 0 0 1/32 1/16

1 0 1 1/64 1/32

1 1 0 1/128 1/64

1 1 1 1/256 1/128

El preescaler se comparte exclusivamente entre el Timer0 y el WDT. El preescaler no es de

lectura/escritura.

Nota. Escribir en TMR0, cuando el preescaler es asignado a Timer0, limpia la cuenta del

preescaler, pero no cambia el contenido del preescaler.

Observación: 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 instrucción CLRWDT limpiará no solo el timer

del watchdog, sino también el preescalador.

A manera de resumen se presenta a continuación una descripción de los bits del registro

OPTION_REG que tienen relación con el timer 0:

Page 8: 6 El Módulo Temporizador PIC

8

bits 5 T0CS.- Bit de selección 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 instrucción interno (CLKout) (modo temporizador).

bit 4 T0SE.- Bit de selección de transición activa del reloj en modo contador. Un 1 en este bit

selecciona el incremento de TMR0 en la transición de alto a bajo de T0CKI, mientras

que un 0 selecciona la la transición de bajo a alto.

bit 3 PSA.- Bit de asignación 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 selección del valor del preescaler (ver tabla anterior).

TABLA DE REGISTROS ASOCIADOS AL TIMER0

Dirección 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 --- --- Registro de direccionamiento de datos del PORTA --11 1111 --11 1111

Leyenda: x = desconocido, u = inalterado; - = no implementado se lee como ‘0’. Las celdas

sombreadas no son usadas por el TIMER0

1.2. El Módulo del Timer 1

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 leíbles 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 interrupción, 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 módulo, en donde se indican

los bits que afectan su operación y la manera en que lo hacen.

Page 9: 6 El Módulo Temporizador PIC

9

Nota 1: Cuando el bit T10SCEN está desactivado, el invertir está apagado. Esto elimina el gasto

de energía

1. Modo temporizador

En este modo el Timer 0 se incrementa (si no se considera preescalador) en cada ciclo de

instrucción (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

señal de reloj es el reloj interno del microcontrolador FOSC/4. En este modo de trabajo

el bit T1SYNC (T1CON <2>) no tiene ningún 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 sólo uno de 4 valores: 1/1, 1/2, 1/4 y 1/8.

2. Modo contador

El Timer 1 también 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.

En este modo puede trabajar como contador síncrono o asíncrono. Cuando el TIMER1 se

está incrementando según le llegan los impulsos externos, los incrementos ocurren en los

flancos de subida. Después de que el TIMER1 se ha configurado como contador, debe

producirse un flanco de bajada antes de empezar a contar.

Nota. Las flechas indican los incrementos del contador.

Page 10: 6 El Módulo Temporizador PIC

10

Modo de funcionamiento del Timer1 como Contador Síncrono

Para seleccionar este modo se pone a uno el bit TMR1CS (T1CON <1>). En este modo el

contador se incrementa en cada flanco ascendente de la señal de reloj que se introduce por el pin

RC0/T1OSO/TICK1 cuando el bit T1OSCEN está a uno, y por el pin RC1/TlOSI/CCP2, cuando

el bit T1OSCEN está a cero.

Si T1SYNC se pone a cero, entonces la entrada de reloj externa se sincroniza con los relojes de

fase interiores. La sincronización se hace después de la fase del preescaler. En el preescaler la

fase de la señal de reloj es por lo tanto asíncrona.

En este modo de trabajo, durante el modo SLEEP el TIMER1 no se incrementa aún cuando la

señal de reloj externa esté’ presente. El preescaler sin embargo continúa incrementándose.

Modo de funcionamiento del TIMER1 como Contador Asíncrono

Cuando el bit de control T1SYNC (T1CON <2>) se poner a uno, la señal de reloj externa no se

sincroniza. El contador sigue realizando la cuenta de forma asíncrona respecto a la fase de la

señal de reloj interna. El contador continua la cuenta incluso en el modo SLEEP y puede generar

una interrupción por desbordamiento que despierta al procesador. Hay que tener especial

cuidado con el software al leer o escribir el contador (Sección 6.5.1).

Cuando se trabaja en el modo contador asíncrono, el TIMER1 no puede usare como base de

tiempos para el módulo CCP (Captura y comparación-PWM).

Lectura y escritura en el TIMER1 cuando se trabaja en el modo contador asíncrono

Se pueden leer los contadores TMR1H y TMR1L mientras la señal externa del contador se está

recibiendo (teniendo cuidado con el hardware). Sin embargo, el usuario debe tener en cuenta

que el contador es de 16 bits y se pueden tener ciertos problemas al leer los dos registros de ocho

bits, ya que el contador puede desbordarse entre las lecturas.

Para escribir en él, se recomienda que el usuario simplemente pare el contador y escriba los

valores deseados. Cuando se escribe el registro del contador puede haber conflicto mientras este

se está incrementando. Esto puede producir un valor imprevisible en el contador.

Oscilador del TIMER1

Se puede conectar un oscilador a cristal entre los pines T1OSI (entrada) y T1OSO (salida del

amplificador). Se debe habilitar poniendo a uno el bit de control TLOSCEN (TICON <3>). El

oscilador de bajo consumo puede trabajar hasta 200 kHz. En estas condiciones el oscilador sigue

funcionando aunque se fuerce el modo SLEEP. Está pensado para trabajar con un cristal de 32

kHz. La Tabla 6 muestra el valor de los condensadores para el TIMER1.

El oscilador TIMER1 es idéntico al oscilador LP. El usuario debe proporcionar un tiempo de

retardo por software para asegurar la salida apropiada del oscilador. En la siguiente tabla se

muestra la selección de los condensadores para el oscilador del TIMER1

Page 11: 6 El Módulo Temporizador PIC

11

Tipo de Oscilador Frecuencia C1 C2

LP 32 kHz 33pF 33pF

100kHz 15 pF 15 pF

200 15 pF 15 pF

Estos valores son para los siguientes cristales de referencia

32.768 EpsonC-001R21.768K-A ±20 PPM

100 kHz Epson C-2 100.000 KC-p1 ±20 PPM

200 kHz STD XTL 200.000 kHz ±20 PPM

Notas: 1. Capacidades mayores aumentan la estabilidad del oscilador, pero también aumentan el

start-up.

2. Cada cirstal/resonador tiene sus propias características, el usuario debe consultar los

valores apropiados de los componentes externos al cristal.

RESTABLECIMIENTO DEL TIMER1 UTILIZADO LA SALIDA TRIGGER DEL CCP

Si el módulo CCPI o CCP2 se configuran en modo comparación para generar un “disparo por

evento especial” (CCP1M3:CCP1MO = 1011), esta señal reestablecerá el TIMIER1.

Nota. El evento especial que activa los módulos CCP1 y CCP2 no activará el flag TMR1IF

(PIR1<0>).

El TIMER1 debe configurarse como temporizador o contador síncrono

Restablecimiento TIMER1 que usa un disparador de CCP

TIMER1 debe configurarse para temporizador o contador síncrono para aprovechar esta

característica. Si el TIMER1 está trabajando en modo contador asíncrono, el reset no puede ser

activado.

En el caso de escribir sobre el TIMER1 en el momento del disparo del evento especial de CCP1

o CCP2, se tomará el valor anterior.

En el caso de escribir sobre TIMER1 si coincide con un disparo por evento especial de CCP1 o

CCP2, se carga el valor anterior.

En este modo de funcionamiento, el par de registros CCPRxH:CCPRxL se reponen para volver

a tener el periodo del TIMER1.

Restablecimiento del par de registro del TIMER1 (TMR1R, TMR1L)

Los registros TMR1H y TMR1L no se inicializan a 00h después de un Power-on Reset o por

cualquier otro reset excepto por un disparo de evento especial en CCP1 y CCP2.

El registro T1CON se inicializa a 00h después de un Power-on Reset o Brown-out Reset que

deja a 1:1 el preescaler. En los demás reset, el registro no es alterado.

El contador del preescaler se pone a cero al escribir en los registros TMR1H o TMR1L.

Page 12: 6 El Módulo Temporizador PIC

12

Otras características

El Timer 1 también posee un bit para habilitación/deshabilitación, este es el bit

TMR1ON (T1CON<0>) y habilita en alto.

Además, el Timer 1 posee una entrada interna de RESET, el cual puede ser activado por uno

cualquiera de los módulos CCP que se describirán más adelante.

A continuación se describe el principal registro relacionado con el Timer 1 y todos sus bits,

excepto los que tienen que ver con el modo contador:

bits 5:4 T1CKPS1:T1CKPS0.- Bits de selección del valor del divisor de frecuencia del

preescalador:

0 0 = divisor 1/1

0 1 = divisor 1/2

1 0 = divisor 1/4

1 1 = divisor 1/8

Observación: 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 selección 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 habilitación / deshabilitación del Timer 1:

1 = habilita Timer 1

0 = Deshabilita Timer 1

Modos de trabajo del TIMER1

EL TIMERl tiene los siguientes modos de trabajo:

1. Como Temporizador

2. Como contador Síncrono

3. Como contador Asíncrono

El modo de trabajo viene determinado la fuente de los impulsos de reloj, es decir, la señal de

reloj puede ser externa o interna, se selecciona con el bit TMRLCS del registro TlCON<l>,

cuando este bit está a nivel bajo se selecciona el reloj el interno del micro-controlador (Fosc/4) y

cuando está a uno se selecciona el modo contador y cuenta los impulsos que le llegan a través del

pin RC0/TlCKl. Además como se ver más adelante el TIMER1 tiene la posibilidad de

reinicializarse, a partir del módulo CCP.

Page 13: 6 El Módulo Temporizador PIC

13

REGISTRO T1CON: Registro de control del TIMER1 (dirección 10h)

U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0

--- --- T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON

Bit 7 Bit 0

bit 7-6: No implementados: Se lee como “0”

bit 5-4: TlCKPS1:T1CKPS0: bit de selección del preescaler de la señal de reloj

del TIMER1

11 = valor del preescaler 1:8

10 = valor del preescaler 1:4

01 = valor del preescaler 1:2

00 = valor del preescaler 1: 1

bit 3: T1OSCEN: bit de habilitación del oscilador del TIMER1. Cuando se

emplea un oscilador externo, hay que poner este bit a 1. El TMR1 puede

trabajar a una frecuencia totalmente independiente de la del sistema.

1 = Habilita el oscilador

0 = Deshabilita el oscilador

Nota. El oscilador y la resistencia de

desconectan para reducir el consumo

bit 2: #TlSYNC: bit de control de sincronización de la señal de entrada.

Con TMR1CS = 1

1= No sincroniza la entrada de reloj externa

0 = Sincroniza la entrada de reloj externa

Con TMR1CS = 0

En esta condición se ignora. El TIMER1 utiliza el reloj interno cuando

TMRICS=0

bit 1: TMR1CS: bit de selección de la fuente de reloj del TIMER1

1 = Reloj externo por el pin RC0/T1OSO/T1CK1 (flanco ascendente)

0 = Reloj interno (FOSC/4)

bit 0: TMR1ON: TIMER1. activo. Hace entrar o no en funcionamiento el

TIMER1.

1 = Habilita el TIMER1

0 = Deshabilita el TIMER1

RESUMEN DE REGISTROS ASOCIADOS AL TIMER1

En la siguiente tabla se muestran los registros principales que controlan el comportamiento del

TIMER1 y la distribución de los bits.

Page 14: 6 El Módulo Temporizador PIC

14

Dirección 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 TOIF 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

0Eh TMR1L Registro de carga del byte de menor peso del registro de 16 bits de TMR1 xxxx xxxx uuuu uuuu

0Fh TMR1H xxxx xxxx uuuu uuuu

10h T1CON --- --- T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON --xx xxxx --uu uuuu

Leyenda: x = desconocido, u = inalterado; - = no implementado se lee como ‘0’. Las celdas

sombreadas no son usadas por el TIMER1.

Nota 1: Los bits PSPIE y PSPIF están reservados para el PIC16F873/876, mantener estos bit a

cero.

1.3. El Módulo del Timer 2

El Timer es un temporizador (sin opción 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 módulo del Timer2.

a. 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>)

b. El Registro de comparación o de Periodo

En operación, 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

además se genera una señal de salida, la cual es tratada por un postescalador, para poder

generar una señal TMR2IF (PIR1<1>) que puede ser usada para solicitar una interrupción,

Page 15: 6 El Módulo Temporizador PIC

15

o para ser leída por poleo.

c. El Postescalador

El postescalador divide la frecuencia con que ocurre una activación 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 activación, esto puede ser hecho en la rutina de atención a la

interrupción, o bien en la rutina que la detecta por poleo.

El valor de división del postescalador puede establecerse por software mediante los bits

T2OUPS3:T2OUPS0 (T2CON<6:3>).

A continuación se describe el principal registro relacionado con el Timer 2 y todos sus bits.

bits 6:3 T2OUPS3:T2OUPS0.- Bits de selección 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

1 1 1 1 = divisor 1/116

Observación: 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 configuración 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

Operaciones con el TIMER2

El Timer2 tiene emparejado el registro PR2 que ocupa la posición de 92H del banco de registros

especiales, de manera que al incrementarse TMR2 y coincidir con el valor del registro PR2 se

produce un impulso de salida, estos impulsos pueden ser divididos por un postescaler antes de

activar el flag TMR2FI (PIR1<1>).

Page 16: 6 El Módulo Temporizador PIC

16

El registro PR2 es un registro de 8 bits que puede ser escrito y leído, este registro toma el valor

FF después de un Reset.

El postscaler permite dividir la señal por cualquier valor comprendido entre 1:1 hasta 1:16, para

controlar el postescaler se utilizan los bit TOUTPS3: TOUTPS0 (T2CON <6:3>).

El Preescaler y el Postescaler se ponen a cero cuando:

• Se escribe sobre el registro TMR2

• Se escribe sobre el registro T2CON

• Se produce un reset (POR, MCLR restablecido, WDT reestablecido o BOR)

TMR2 no se pone a cero cuando se escribe en T2CON

REGISTRO T2CON: REGISTRO DE CONTROL DEL TIMER2 (dirección 12h)

U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0

--- TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0

Bit 7 Bit 0

bit 7: No implementado: Se lee como 0

bit 6-3: TOUTPS3:TOUTPS0: bit de selección 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

1101 = Divisor del postescaler 1:14

1110 = Divisor del postescaler 1:15

1111 = Divisor del postescaler 1:16

bit 2: TMR2ON: bit de activación del TIMER2

1:= habilita el funcionamiento del TIMER2

0 = Inhibe el funcionamiento del TIMER2

bit 1-2: T2CKPS1:T2CKPS0 Selección del rango de divisor del Preescaler del TIMER2

00 = Divisor del Preescaler 1:1

01 = Divisor del Preescaler 1:4

Page 17: 6 El Módulo Temporizador PIC

17

Ix = Divisor del Preescaler 1:16

Interrupciones del TIMER2

El temporizador TMR2 tiene un flag de desbordamiento el TMR2IF (<1>PIR1).

El TMR2 tiene asociado un Registro de Periodo PR2, que ocupa la posición 92h. Cuando el

valor de cuenta de TMR2 coincide con el valor cargado en PR2 se genera un impulso en la

salida EQ (ver la Figura 16 ) y se pone a cero el TMR2. Estos impulsos pueden ser divididos por

el postdivisor antes de activar el flag TMR21F(<1> PIR1).

El temporizador puede producir una interrupción si se pone a 1 el bit TMR2IE (<1> PIE1)

Salida del TMR2

La salida de TMR2 (antes del postscaler) alimenta al Módulo de SSP que opcional mente puede

usarse para generar la señal de reloj de desplazamiento.

REGISTROS ASOCIADOS AL TMR2

Dirección 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

11h TMR2 Módulo Del registro Timer2 0000 0000 0000 0000

12h T2CON --- TOUTPS3 TOUPS2 TOUPS1 TOUPS0 TMR2ON T2CKPS1 T2CKPS0 -000 000 -000 0000

92h PR2 Registro de período del TMR2 1111 1111 1111 1111

Leyenda: x = desconocido, u = inalterado; - = no implementado se lee como ‘0’. Las celdas

sombreadas no son usadas por el TIMER2

Nota 1: Los bits PSPIE y PSPIF están reservados para el PIC16F873/876, mantener estos bits a

cero.

Ejemplo 1

Manejo del Timer 0 como contador

El siguiente programa realiza el conteo del número de veces que produce una transición

de bajo a alto en la patita T0CKI. El valor del contador se incrementará una vez por cada

dos transiciones y será enviado a través del puerto serie para ser desplegado en la

pantalla de una PC.

Page 18: 6 El Módulo Temporizador PIC

18

;**************************************************************************** ;* Este programa realiza el conteo de una señal conectada a la patita T0CKI * ;* el valor del contador lo envía a través 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 transmisión

BCF STATUS,RP0 ;Banco 0 CLRF TMR0 ;inicializa la cuenta de TMR0 BSF STATUS,RP0 ;Banco 1 MOVLW 0xE0 ;dato de configuración para el timer0 MOVWF OPTION_REG ;configura modo contador, transición positiva,

;preescalador 1/2 asignado a timer0 BCF STATUS,RP0 ;Banco 0

ciclo MOVF TMR0,W ;lee cuenta actual CALL Envbyte ;envía el valor por el puerto serie MOVLW 0x0D ;carga carácter <CR> CALL envia ;lo envía MOVLW 0x0A ;carga carácter <LF> CALL envia ;lo envía GOTO ciclo ;repite

;*************************************************************** ; Subrutina que envía el byte en W por el puerto serie, separado ; en los códigos 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 ;máscara 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 código ASCII equivalente CALL envia ;lo envía por el puerto serie MOVF lsnib,W ;carga lsnib en W CALL asc ;obtiene código ASCII equivalente CALL envia ;lo envía por el puerto serie RETURN

asc ADDWF PCL,1 ;Calcula el código 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 asíncrono) BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisión) BCF STATUS,RP0 ;regresa al banco 0 BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie) RETURN

Page 19: 6 El Módulo Temporizador PIC

19

;*************************************************************** ;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 transmisión

GOTO esp ;si está ocupado espera BCF STATUS,RP0 ;regresa al banco 0 MOVWF TXREG ;envía dato guardado en W RETURN end

Observación. Mediante el programa anterior podemos realizar el conteo de pares de “rebotes”

provocados por un botón pulsador, basta con conectar la salida de dicho botón a la patita

T0CKI. Al hacer lo anterior se verá que por cada pulsación del botón se incrementa la cuenta no

de uno en uno, sino en un valor mayor por el efecto de los rebotes. Esto también quiere

decir, que si no deseamos que el contador se vea afectado por el rebote de la señal a contar,

se deberá incluir un limpiador de rebotes por hardware, externo al PIC.

Análisis del código

En primer lugar configuramos el registro OPTION_REC.

Registro OPTION_REC

OPTION_REC = E0

#RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0

1 1 1 0 0 0 0 0

Bit 7 Bit 0

T0CS = 1, Seleccionado como reloj la patita T0CKI (modo contador)

T0SE = 0, El incremento de TMR0 en la transición de bajo a alto de T0CKI

PSA = 0, Asigna el preescalador al Timer0.

PS2=0, PS1=0 y PS0=0; Bits de selección del valor del preescaler a 1/2

Programa principal. Este programa lee el valor de la cuenta actual de TMR0, envía el valor por el puerto

serie, luego carga el carácter <CR> y lo envía, y también carga el carácter <LF> y lo envía.

Subrutinas. Son tres: Envbyte, initrans y envia:

Envbyte. Subrutina que envía el byte W por el puerto serie, separados en los códigos ASCII de

sus dos nibbles hexadecimales.

Registro TMR0:

Bit 7 Bit 0

Almacenar los nibles de TMR0 en msnib y lsnib, como se muestra en los siguientes gráficos.

msnib

Page 20: 6 El Módulo Temporizador PIC

20

Bit 7 Bit 0

lsnib

Bit 7 Bit 0

Initrans. Subrutina para inicializar el puerto serie USART como transmisor a 9600 Bauds,

considerando un cristal de reloj de 14.7456 MHZ.

envia. Subrutina para enviar el byte guardado en W por el puerto serie.

Ejemplo 2

Manejo del Timer 0 como temporizador

El siguiente programa utiliza el timer 0 para realizar una pausa de máxima duración, 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 sólo 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 duración (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 duración máxima M = 256, N = 256 tendremos:

TH = TMAX = 262144/Fosc

Para un reloj de 14,7456 Mhz tendremos

TH = TMAX = 17,777... mseg

F = 1/(2 TH) = 1/(2*17,777 ms)

F = 28,125 Hertz

Y la frecuencia de parpadeo del LED será F = 28,125 Hertz.

Page 21: 6 El Módulo Temporizador PIC

21

Es decir,

TH = Tciclo = N*M*(4/Fosc)

Fciclo = Fosc/4 * 1/M * 1/N

donde:

Fosc/4, Frecuencia de oscilación (cuenta Timer0)

1/M, Divisor de frecuencia

;***************************************************************** ;* Este programa hace parpadear un LED conectado a la patita RC0 * ;* Usa el timer 0 para generar una pausa de 17.777777 mseg de * ;* duración (supone un cristal de 14.7456 Mhz). La frecuencia de * ;* parpadeo del LED es de 28.125 Hertz aprox. * ;*****************************************************************

Include "p16f877.inc"

org 0x0000 call iniciatimer0

inic BSF STATUS,RP0 ;Banco1 BCF TRISC,0 ;patita RC0 como salida BCF STATUS,RP0 ;Banco 0

rep 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 configuración timer 0 ;************************************* iniciatimer0 N1 EQU 0x00

BCF INTCON,T0IF ;limpia bandera de sobreflujo BSF STATUS,RP0 ;Banco 1 MOVLW 0xC7 ;dato de configuración para el timer0 MOVWF OPTION_REG ;modo temporizador, preescalador 1/256 asignado a timer0 BCF STATUS,RP0 ;Banco 0 Return

;* Subrutina de pausa de 17.77 mseg ;************************************* pausa

MOVLW N1 ;número de incrementos del timer MOVWF TMR0 ;inicializa la cuenta de TMR0

repite BTFSS INTCON,T0IF ;checa bandera de sobreflujo (cambio de 255 a 0)

GOTO repite ;si no se ha activado, espera BCF INTCON,T0IF ;si ya se activó, la desactiva RETURN ;retorna

end

Análisis del código

En primer lugar configuramos el registro OPTION_REC.

Registro OPTION_REC

Page 22: 6 El Módulo Temporizador PIC

22

OPTION_REC = C7

RBPU# INTEDG T0CS T0SE PSA PS2 PS1 PS0

1 1 0 0 0 1 1 1

Bit 7 Bit 0

T0CS = 0, Selecciona el reloj del ciclo de instrucción interno (CLKout) (modo temporizador)

T0SE = 0, No importa

PSA = 0, Asigna el preescalador al Timer0.

PS2=1, PS1=1 y PS0=1; Bits de selección del valor del preescaler a 1/256

Programa principal. Este programa configura el timer 0 y chequea la bandera de sobre flujo (cambio de

255 a 0), si no se ha activado T0IF espera, si ya se activó la desactiva.

Subrutinas. Exite una subrurina pausa:

Pausa, es una subrutina de pausa de 17.77 mseg, donde N1 es el valor inicial del Timer 0.

Observación. La rutina de pausa se puede modificar para una duración de N

incrementos del Timer 0, simplemente definiendo N1 como valor inicial, es decir:

N1 = 256 – N

donde:

N1, Cuenta inicial del Timer0

N, Incrementos Timer0

Para el cálculo de cualquier tiempo

tiempo = Tciclo * Mz

donde:

Tciclo, Duración del ciclo

Mz, Número cruces por cero o número 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

Page 23: 6 El Módulo Temporizador PIC

23

El valor de Mz siempre debe ser un valor entero.

El código para la subrutina de 1seg, será:

Count RES 1 delay ;El valor inicial del TMR0 es 6 movlw 6 movwf TMR0 ;El registro Count se inicializa a 125 cruces por cero movlw 125 movwf Count ;Lazo de conteo DelayLoop ;TMR0 vale 0 ? movf TMR0,W btfss STATUS,Z goto DelayLoop ;No, espera... movlw 6 ;Si, reinicializa TMR0 a 6 movwf TMR0 decfsz Count,1 ;cuenta 125 cruces por cero goto DelayLoop return

Nota: Para un reloj de 4 Mhz, una duración máxima M = 256, N = 256 tendremos:

Tciclo = N*M*(4/Fosc)

Tciclo = TMAX = 256*256* (4/Fosc)

Tciclo = TMAX = 65,536 mseg

Ejemplo Práctico

Realizar un intermitente con cuatro leds cuya frecuencia de intermitencia con un retardo igual a

un segundo utilizando el registro TMR0.

El código de este ejemplo está disponible en SEQTMR0.ASM y se muestra a continuación:

;************************************************** ; ; SEQTMR0.ASM ; ;************************************************** PROCESSOR 16F877 RADIX DEC INCLUDE "P16F877.INC" ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer

Page 24: 6 El Módulo Temporizador PIC

24

;Enable power up timer ;Disable code protect

__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

ORG 20H Count RES 1 Shift RES 1 ;Vector Reset - Punto de inicio del programa al reset de la CPU ORG 00H ;Conmuta al segundo banco de registros bsf STATUS,RP0 ;Definicion de las lineas de I/O (0=Salida, 1=Ingreso) movlw 11110000B movwf TRISB ;Asigna el PRESCALER a TMR0 en la configuracion a 1:32 movlw 00000100B movwf OPTION_REG ;Conmuta al primer banco de registro bcf STATUS,RP0 ;El registro Shift viene utilizado para representare internamente ;El bit 0 del registro Shift viene seteado a uno para iniciarlizar ;el ciclo del primer led. movlw 00000001B movwf Shift ; Bucle de flujo MainLoop ;Envia el Puerto B al registro Shift de modo que cada bit es uno ;en Shift para que se enciende el LED movf Shift,W movwf PORTB ;Para encender las luces debe utilizar la instrucción RLF ;hacer el cambio a la izquierda de los bits contenidos en ;un registro y el bit 0 del estado del bit carry ;Por esta razón, antes de la instrucción RLF borrar el bit ;de acarreo de la instrucción ;bcf STATUS,C. bcf STATUS,C rlf Shift,F ;Cuando llega el turno de los 4 bits se invierte los primeros ;cuatro bits del registro Shift con los segundos cuatro bits, ; con el fin de reiniciar el ciclo desde el bit 0. ; ;¿Qué pasa con los bits del registro de cambio durante ;la ejecución de este bucle?: ; ; 00000001 <--- Valor inicial (primer led de acceso)

Page 25: 6 El Módulo Temporizador PIC

25

; 00000010 rlf ; 00000100 rlf ; 00001000 rlf ; 00010000 rlf En este momento se ejecuta la instrucción swapf ;obteniendo: ; 00000001 ... por lo que forma btfsc Shift,4 swapf Shift,F ;Introducir un retraso entre el encendido y el otro call Delay ; Volver a ejecutar el bucle goto MainLoop ;************** ; Subrutinas ;************** ;Inserción de un retraso de un segundo utilizando el ;registro TMR0 ; ;El retraso se obtiene de la frecuencia de salida del ;PRESCALER igual a: ;4Mhz / 4 / 32 = 31.250 Hz ;... dividido por 250 del TMR0 de 32.250 / 250 = 125 Hz ;... y por 125 del contator Count 125 / 125 = 1Hz Delay ;Inicializar TMR0 para obtener una cuenta de 250 antes de llegar ;a cero. ;El registro TMR0 y un registro de 8 bits, por lo que si ;es mayor nuevamente cuando se trata de 255 comienza ;a contar desde cero. ;Si es inicializado a 6 debe ser incrementado de 256 a 6 = 250 ;veces. ;Primer paso por cero. movlw 6 movwf TMR0 ;El registro de la cuenta se inicializa a 125 debido a su ;propósito y salir del bucle movlw 125 movwf Count ;Lazo de contar DelayLoop ;TMR0 vale 0 ? movf TMR0,W btfss STATUS,Z goto DelayLoop ;No, espera... movlw 6 ;Si, TMR0 reinicia y comprueba si movwf TMR0 ;ha pasado 125 veces por cero

Page 26: 6 El Módulo Temporizador PIC

26

decfsz Count,1 goto DelayLoop return END

Análisis del código SEQTMR0.ASM

En primer lugar programar el PRESCALER para obtener una frecuencia de conteo apropiada,

insertando las siguientes instrucciones al inicio del programa:

movlw 00000100B movwf OPTION_REG

En la práctica 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 más adelante) y los bits de configuración del PRESCALER a 100

para obtener una frecuencia de división igual a 1:32. Como se muestra el registro OPTION en la

figura 7.

RBU INTDEG T0CS T0SE PSA PS2 PS1 PS0

0 0 0 0 0 1 0 0

La frecuencia de conteo que se obtiene en TMR0 será igual a:

Fosc = 1Mhz / 32 = 31.250 Hz

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 6

movwf TMR0

y movlw 125

movwf Count

Las primeras dos almacenan en TMR0 el valor 6 de modo que el registro TMR0 alcanza el cero

después 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.

Page 27: 6 El Módulo Temporizador PIC

27

Cuando Count alcance también 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 continuación se describe un programa similar al ejemplo 16, en el cual se utiliza el Timer

1 para realizar una pausa de máxima duración, 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 sólo 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 duración (Tciclo) del ciclo

será:

T = Tciclo = N*M*(4/Fosc)

Así, para una duración máxima M = 8, N = 65536 tendremos:

TMAX = 2097152/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 * ;* duración (supone un cristal de 14,7456 Mhz). La frecuencia de * ;* parpadeo del LED es de 3,515625 Hertz aprox. * ;*****************************************************************

Include "p16f877.inc" org 0x0000

call iniciatimer1

inic BSF STATUS,RP0 ;Banco1 BCF TRISC,0 ;patita RC0 como salida BCF STATUS,RP0 ;Banco 0

rep BSF PORTC,0 ;enciende LED CALL pausa ;pausa de 71.11 mseg BCF PORTC,0 ;apaga LED CALL pausa ;pausa de 71.11 mseg

Page 28: 6 El Módulo Temporizador PIC

28

GOTO rep

;* Subrutina configuración timer 1 ;************************************* iniciatimer1 N1 EQU 0x00 N0 EQU 0x00

BCF PIR1,TMR1IF ;limpia bandera de sobreflujo MOVLW 0x31 ;dato de configuración para el timer1 MOVWF T1CON ;modo temporizador, preescalador 1/8, habilita timer 1 return

;* Subrutina de pausa de 71.111 mseg ;************************************* pausa MOVLW N1 ;número de incrementos del timer msb

MOVWF TMR1H ;inicializa la cuenta de TMR1 MOVLW N0 ;número de incrementos del timer lsb MOVWF TMR1L ;inicializa la cuenta de TMR1

Repite BTFSS PIR1,TMR1IF ;checa bandera de sobreflujo (cuenta=65536) GOTO repite ;si no se ha activado, espera BCF PIR1,TMR1IF ;si ya se activó, la desactiva RETURN ;retorna end

Observación 1: El programa es idéntico al ejemplo 2, lo único que cambia son las subrutinas de

iniciatimer1 y pausa, las cuales ahora se han realizado con el timer 1 y no con el Timer 0

Observación 2: La rutina de pausa se puede adaptar para una duración de N ciclos del

Timer 1, simplemente definiendo como N1:N0 valores iniciales, por lo que N es lo falta para

ser 65536, es decir:

N1:N0 = 65536 - N

Por ejemplo, utilizando el Timer1 obtener un Delay de 1.5 seg, con una frecuencia de

oscilación de 4 MHz.

Primero se calcula el Tciclo máximo con los siguientes valores:

N = 65536; es el máximo valor que alcanza con FFFF

M = 8; es el valor máximo 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 número de cruces por cero Mz, porque no alcanza Tciclomax = 524,288

mseg a los 1.5 seg, mediante la siguiente ecuación:

tiempo = Tciclo * Mz

Mz = tiempo / Tciclo

Mz = 1,5 seg / 0.524288 seg

Mz = 2,86102

Page 29: 6 El Módulo Temporizador PIC

29

Pero Mz no es entero, por lo que se debe hacer un nuevo cálculo con un nuevo Tciclo, en donde:

tiempo = 1.5 seg

Tciclo = 12 mseg (se escoge cualquier valor entero múltiplo 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:

T = Tciclo = N*M*(4 / fosc)

Donde:

M = 8 (Valor del preescalador de 1/8)

Fosc = 4MHz

12 mseg = N * 8 *(4 / 4 MHz)

N= (12 mseg * 4MHz) / 32

N= 1500

Por último, se debe determinar el valor inicial de la cuenta del Timer1:

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 ;número de incrementos del timer msb MOVWF TMR1H ;inicializa la cuenta de TMR1 MOVLW N0 ;número de incrementos del timer lsb MOVWF TMR1L ;inicializa la cuenta de TMR1 BCF PIR1,TMR1IF ;limpia bandera de sobre flujo MOVLW 0x31 ;dato de configuración para el timer1 MOVWF T1CON ;modo temporizador, preescalador 1/8, ;habilita timer 1

Page 30: 6 El Módulo Temporizador PIC

30

ciclo BTFSS PIR1,TMR1IF ;checa bandera de sobre flujo (cuenta=65536)

GOTO ciclo ;si no, se ha activado, espera decfsz Mz,1 goto Delay15s return

Ejemplo 4

Manejo del Timer 2 como temporizador.

¿Cuál es la máxima duración 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 sóla activación

de TMR2IF?.

Solución.

Sea Tciclo la duración 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 duración de

la pausa dada por

Tciclo = N*M*P*(4/Fosc)

Así, para una duración máxima P = M = 16, N = 256 tendremos:

TcicloMAX = 262144/Fosc

Para un reloj de 14,7456 Mhz tendremos

TcicloMAX = 17,777... mseg

Nota: Como se puede apreciar el TcicloMAX del Timer2 es igual al TcicloMAX del Timer0.

Page 31: 6 El Módulo Temporizador PIC

31

1.4. Los Módulos de CCP (Captura / Comparación / PWM)

El PIC16F87X posee dos módulos CCP, denominados CCP1 y CCP2. Ambos módulos son

prácticamente idénticos con la excepción de la operación del disparo de evento especial.

Cada uno de estos dos módulos poseen un registro de 16 bits, el cual puede operar como:

• Registro de captura de 16 bits

• Registro de comparación de 16 bits

• Registro de Ciclo de Trabajo del módulo PWM de 8 bits.

Cada modo de operación requiere como recurso uno de los timers del PIC. En la

siguiente tabla se muestran los timers usados por cada modo:

Modo de operación

del CCP

Recurso

utilizado Captura Timer 1

Comparación Timer 1

PWM Timer 2

A continuación se da un breve resumen de los registros relacionados con cada módulo:

a. El Módulo CCP1

El registro principal de este módulo (CCPR1) se compone de dos registros de 8 bits,

denominados CCPR1H (16h) (parte más significativa) y CCPR1L (15h) (parte menos

significativa). La operación del módulo se controla mediante el registro CCP1CON y el

disparo de evento especial, el cual es generado al alcanzarse la igualdad en un registro de

comparación reseteará el Timer 1.

b. El Módulo CCP2

El registro principal de este módulo (CCPR2) se compone de dos registros de 8 bits,

denominados CCPR2H (parte más significativa) y CCPR2L (parte menos significativa). La

operación del módulo se controla mediante el registro CCP2CON y el disparo de evento

especial, el cual es generado al alcanzarse la igualdad en un registro de comparación

reseteará el Timer 1, e iniciará una conversión analógico/digital (si el módulo

convertidor A/D está habilitado). Esta última característica es la diferencia entre los dos

módulos.

Selección del modo de operación

La selección del modo en que trabajara el módulo CCPx se realiza mediante los cuatro bits

menos significativos del registro CCPxCON, es decir, mediante los bits

CCPxM3:CCPx0 (CCPxCON<3:0>) de acuerdo a la siguiente tabla

CCPxM3:CCPxM0 Modo seleccionado

0 0 0 0 Captura/Comparación/PWM deshabilitados

0 1 0 0 Captura cada transición de bajada

0 1 0 1 Captura cada transición de subida

Page 32: 6 El Módulo Temporizador PIC

32

0 1 1 0 Captura cada cuarta transición de subida

0 1 1 1 Captura cada 16 transiciones de subida

1 0 0 0 Comparación, pone salida cada coincidencia

1 0 0 1 Comparación, limpia salida cada coincidencia

1 0 1 0

Comparación, genera interrupción cada coincidencia (salida

inalterada)

1 0 1 1

Comparación, dispara evento espacial (CCP1 resetea TMR1; CCP2

resetea TMR1 y arranca una conversión A/D).

1 1 x x Modo PWM

A continuación se describe a detalle cada uno de los modos de operación, comenzando con el

modo PWM. La descripción se realiza sólo para el módulo CCP1, ya que es prácticamente

igual al CCP2.

INTERACCIÓN DE LOS DOS MÓDULOS CCP

Modo CCPx Modo CCPy Interación

Captura Captura La misma base de tiempos de TMR1

Captura Comparación El comparador debe configurarse para el modo de

disparo especial que pone a cero el TMR1

Comparación Comparación El Comparador(es) debe configurarse para el modo de

disparo especial que pone a cero el TMR1

PWM PWM El PWM tendrá la misma frecuencia y proporción de

actuación (interrupción de TMR2)

PWM Captura Ninguna

PWM Comparación Ninguna

Registro CCP1CON (dirección 17h)/Registro CCP2CON (dirección 1Dh)

U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0

--- --- CCPxX CCPxY CCPxM3 CCPxM2 CCPxM1 CCPxM0

Bit 7 Bit 0

bit 7-6: No implementados: Se lee como "0"

bit 5-4: CCPxX: CCPxY: bit menos significativos de PWM

Modo Captura sin usar

Modo Comparación sin usar

Modo PWM: Estos dos bit son los menos significativos del ciclo de PWM. Los ocho bits

más significativos se encuentran en CCPRXL.

bit 3-0:CCPxM3-.CCPxM0; bit de selección del modo de trabajo del módulo comparador

CCPX.

CCPxM3: CCPxM0

MÓDO DE TRABAJO DEL MÓDULO

0000 Módulo Caputa/Comparación/PWM desactivado (reset del módulo CCPx)

0100 Modo de captura por flanco descendente RCy/CCP

0101 Modo de captura por flanco ascendente en RCy/CCPx

0110 Modo de captura, cada 4 flancos ascendentes en RCy/CCPx

0111 Módo apturador. Cada 16 flancos ascendentes en RCy/CCPx

Page 33: 6 El Módulo Temporizador PIC

33

1000 Modo comparación, activa la patilla, se pone a 1 RCy/CCPx al coincidir los valores

(el bit CCPxIF se pone a uno)

1001 Modo de comparación se pone a 0 la patilla RC/CCPx al coincidir los valores (el bit

CCPxIF se pone a uno)

1010 Modo de comparación, genera una interrupción sofware (el bit CCPxIF se pone a

1, el pin de CCPx no es afectado)

1011 Modo de comparación, en el que se produce un disparo especial para cada

módulo (el bit CCPxIF se pone a uno, el pin CCPx no es afectado); CCP1 resetea

TMR1; CCP2 resetea TMR1 y comienza una conversión de A/D (si el módulo de

A/D se habilita)

11xx Modo de PWM

1. Modo PWM (Modulación 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 resolución de 10 bits, a través de la patita

RC2/CCP1, como se muestra en la figura siguiente:

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

operación básica del PWM.

Page 34: 6 El Módulo Temporizador PIC

34

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. 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 comparación 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 bits

más significativos (msb)) y los dos bits menos significativos (lsb) a

CCP1CON<5:4> este valor de 10 bits lo representaremos como

Page 35: 6 El Módulo Temporizador PIC

35

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 ecuación:

TPWM = CT*TOSC*M

donde, TPWM es el valor de la duración del ciclo de trabajo (CT)

Como se puede ver en la figura anterior, el valor que determina la duración de C.T. del PWM

no es el cargado en CT (CCPR1L), sino en CCPR1H, el cual sólo 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 sólo lectura.

Cuando el valor de TMR2 (concatenado con dos bits internos) alcanza el valor de

CCPR1H (concatenado con dos bits internos también) la patita CCP1 es limpiada (ver figura

anterior.

Como puede ver, el número de divisiones que se pueden tener en un Ciclo de Trabajo

será 2r, donde r es el número de bits usados, por lo tanto su duración máxima será este número

de divisiones multiplicada por la duración del ciclo más pequeño del sistema TOSC. Por lo tanto:

TPWM = (2 r)* TOSC*M

Sin embargo, dependiendo del valor de Ciclo de trabajo máximo (TPWM) deseado, no será

posible realizar las 2r divisiones y por lo tanto no se podrán usar los r bits de resolución.

O al revés, si se elige una resolución deseada r no será posible tener cualquier Ciclo

de Trabajo máximo (TPWM) deseado.

Además, 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 deseamos usar la máxima resolución r

= 10 bits, el ciclo de trabajo máximo posible será (para M=1):

TPWM = 1024*0,05x10-6 = 0,0512 mseg (CT Máxima)

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

por:

PeriodoPWM = (PR2+1)*4*TOSC*M

Despejando PR2 será:

Page 36: 6 El Módulo Temporizador PIC

36

PR2= (PeriodoPWM / (4*TOSC*M)) – 1

Pero si se desea tener el PeriodoPWM máximo se sustituye, PR2=255 = FFh (valor máximo):

PeriodoPWM = (255+1)*4*0,05x10-6 *1

= 0,0512 mseg

O bien, la “Frecuencia del PWM máxima” 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 resolución r y la

correspondiente frecuencia FPWM máxima, así como el valor de PR2 con el que se logra (para

una frecuencia del cristal de 20 Mhz).

FPWM máxima 1.22 Khz 4.88 Khz 19.53 Khz 78.12 Khz 156.3 Khz 208.3 Khz

Preescalador 16 4 1 1 1 1

PR2 FFh FFh FFh 3Fh 1Fh 17h

Resolución

máxima 10 10 10 8 7 5.5

c. Secuencia de configuración del PWM

A continuación se resumen los pasos para realizar la configuración 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 módulo CCP1 para operación PWM. Poniendo en alto los bits

CCP1CON <3:2>.

A continuación se ilustra este proceso de configuración en el siguiente ejemplo.

Ejemplo 5

Control de iluminación en lazo abierto.

En el siguiente ejemplo se ilustra el uso de la salida PWM para controlar el nivel de

iluminación producido por una lámpara de acuerdo a la siguiente figura:

Page 37: 6 El Módulo Temporizador PIC

37

Elección de la frecuencia de operación del PWM:

Como la carga que se desea controlar es de tipo resistivo, no tendrá limitaciones

respecto a frecuencias altas de operación, salvo las limitaciones de baja frecuencia que le

impone la respuesta térmica 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 resolución, repetimos el cálculo del ejemplo anterior, pero ahora

supondremos una FOSC = 14,7456 Mhz, es decir, TOSC = 0,06781684 µseg, entonces, el

ciclo de trabajo máximo posible será (para M=1):

TPWM = (2 r)* TOSC*M, r = 10

TPWM = 1024*0,06781684x10-6 = 0,069444 mseg (CT máximo)

Y para lograr esto, se necesita:

PR2= (PeriodoPWM / (4*TOSC*M)) – 1,

El PeriodoPWM máximo se tendrá sustituyendo, PR2=255 = FFh. (valor máximo)

PeriodoPWM = (PR2+1)*4*TOSC*M

= (255+1)*4*0,06781684x10-6 *1

= 0,06944 mseg

O bien, la “Frecuencia del PWM” definida como FPWM = 1/ PeriodoPWM, tendrá un valor de:

FPWM = 14,4 Khz

;**************************************************************** ;* Este programa controla el ciclo de trabajo de la salida PWM * ;* (patita CCP1) con la cual controlará el nivel de iluminación * ;* promedio producido por una lámpara controlada con esta señal.* ;* Se usa un botón conectado a RB0 para incrementar el nivel y * ;* otro conectado a RB1 para disminuirlo. *

Page 38: 6 El Módulo Temporizador PIC

38

;* Se supone un cristal de 14,7456 Mhz * ;****************************************************************

Include "p16f877.inc" cont EQU 0x20 cont1 EQU 0x21 CTH EQU 0x22 CTL 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 (PR2 = 255) BCF TRISC,2 ;patita RC2/CCP1 como salida BCF STATUS,RP0 ;Banco 0 CLRF CCPR1L ;inicializa Ciclo de Trabajo en cero BCF CCP1CON,CCP1X ;Bits 4 y 5 de CCP1CON menos significativos BCF CCP1CON,CCP1Y ;del ciclo PWM MOVLW 0x04 ;configura Timer 2 MOVWF T2CON ;preescalador 1/1, habilita Timer 2 BSF CCP1CON,CCP1M3 ;Configura el modulo CCP1 para operación 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

Esp0 BTFSC PORTB,0 ;Checa Botón RB0 CALL incre ;si está presionado incrementa CT

Esp1 BTFSC PORTB,1 ;si no se ha presionado Checa botón 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 continuación actualiza la parte alta del CT real MOVLW 0xCF ;máscara ANDWF CCP1CON,1 ;limpia los dos msbits del CT real MOVLW 0x03 ;máscara 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

;************************************************************************************ ;**incrementa parte baja y alta de la copia de CT incre INCF CTL,1 ;incrementa parte baja de la copia de CT

BTFSS STATUS,Z ;checa si se recicló a cero la parte baja RETURN ;si no, retorna INCF CTH,1 ;si se hizo cero la parte baja, incrementa parte alta de CT RETURN

;**decrementa parte baja y alta de la copia de CT 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), ;para ver el valor 11111111 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

Page 39: 6 El Módulo Temporizador PIC

39

GOTO p1 DECFSZ cont1,1 GOTO p1 RETURN END

Análisis del código

En primer lugar configuramos los registros CCPR1L, CCP1CON y T2CON.

Registro CCPR1L

0 0 0 0 0 0 0 0

Bit 7 Bit 0

El registro CCPR1L es el registro que pasa a ser la parte más significativa del ciclo PWM, que comienza

con el valor 0.

Registro CCP1CON

--- --- CCP1X CCP1Y CCP1M3 CCP1M2 CCP1M1 CCP1M0

0 0 1 1 0 0

Bit 7 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 Módulo CCP1 para operación PWM

CCP1M3=1

CCP1M2=1

CCP1M1=0

CCP1M0=0

Registro T2CON

T2CON = 0x04

--- T2OUPS3 T2OUPS2 T2OUPS1 T2OUPS0 TMR20N T2CKPS1 T2CKPS0

0 0 0 0 0 1 0 0

Bit 7 Bit 0

TMR20N = 1, Enciende el Timer 2

Preescaler 1/1

T2OUPS3=0

T2OUPS2=0

T2OUPS1=0

T2OUPS0=0

Programa principal. Este programa comienza la salida PWM con un ciclo de trabajo CT=0

Page 40: 6 El Módulo Temporizador PIC

40

(CTH:CTL), inicializa CT de 10 bits en cero. Luego checa Botón RB0; si está presionado

incrementa CT, si no se ha presionado checa botón RB1; si está presionado decrementa CT, si no

se ha presionado actualiza parte baja del CT real. A continuación realiza el proceso que actualiza

la parte alta del CT real.

Limpia los dos bits menos significativos del CT real en CCP1CON= UU00XXYY, con la

máscara 11001111 (0xCF),

MOVLW 0xCF ;máscara ANDWF CCP1CON,1 ;limpia los dos msbits del CT real

Limpia los seis bits altos en CTH= 000000YY, con la máscara 00000011 (0x03),

MOVLW 0x03 ;máscara ANDWF CTH,1 ;limpia los 6 bits altos en CTH

Copia los 2 bits bajos de CTH= 000000YY en el nibble alto de W=00YY0000,

SWAPF CTH,W ;copia los 2 bits bajos de CTH en el nibble alto de W

Pone los dos bits más significativos de CT real en CCP1CON=UUYYVVXX,

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.

Por último, una pausa para moderar la velocidad de incremento/decremento. Repitiendo todo

nuevamente,

GOTO Esp0 ;repite

El Periodo de PWM es fijo, el CT cambia de 0x000 a 0x3FF.

Subrutinas. Son tres: incre, decre y pau:

incre, incrementa parte baja y alta de la copia de CT.

decre, decrementa parte baja y alta de la copia de CT. No controla cuando todo está en cero.

pau, pausa de 50 milisegundos aproximadamente.

2. El Modo Comparador

En el modo de comparación 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 además de activarse la bandera para solicitar interrupción CCP1IF

(PIR1<2>), puede ocurrir en la patita RC2/CCP1 (previa configuración) alguna de las

siguientes acciones:

• RC2/CCP1 Se pone en alto

• RC2/CCP1 Se pone en Bajo

Page 41: 6 El Módulo Temporizador PIC

41

• RC2/CCP1 no cambia

La acción 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 módulo CCP en modo

comparador

Configuración del modo de comparación

A continuación se hace un resumen de algunas consideraciones que se deberán hacer para

configurar adecuadamente el modo de comparación:

• 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 interrupción, se

deberá limpiar por software antes de un posible evento que la active, de lo

contrario no se notará la activación.

Nota: El manejo de evento especial no se describe en estos apuntes.

Ejemplo 5

Generador de Frecuencia Variable.

En este programa se hace uso del modo de comparación para realizar la conmutación de una

señal cada vez que transcurre un tiempo, el cual se ajusta al oprimir un botón de incremento o

uno de decremento. El hardware utilizado es similar al del ejemplo anterior, sólo que la

salida en lugar de manejar una lámpara, se puede simplemente monitorear mediante un

zumbador piezoeléctrico, o visualizarla en un osciloscopio.

;************************************************************** ;* Este programa genera a través de la patita RC2, una señal * ;* oscilatoria. Se usa un botón conectado a RB0 para incremen-* ;* tar el periodo y otro conectado a RB1 para disminuirlo. * ;* Se supone un cristal de 14.7456 Mhz *

Page 42: 6 El Módulo Temporizador PIC

42

;************************************************************** Include "p16f877.inc" org 0x0000

inic 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 comparación CLRF CCPR1L ;al mínimo (cero) CLRF CCP1CON ;limpia latch de CCP1 BSF CCP1CON,CCP1M3 ;Habilita modulo CCP1 para modo de comparación BCF CCP1CON,CCP1M0 ;pone salida en 1 al coincidir BCF PIR1,CCP1IF ;limpia bandera de interrupción.

checa BTFSS PIR1,CCP1IF ;checa bandera (lazo de espera)

GOTO checa ;si no se ha activado espera BCF PIR1,CCP1IF ;si ya se activó, la limpia MOVLW 0x01 ;máscara XORWF CCP1CON,1 ;conmuta la acción al coincidir próxima comparación. CLRF TMR1L ;limpia la cuenta del timer 1 CLRF TMR1H

BTFSC PORTB,0 ;Checa Botón RB0 CALL incre ;si está presionado incrementa periodo BTFSC PORTB,1 ;si no se ha presionado Checa botón RB1 CALL decre ;si está presionado decrementa periodo GOTO checa ;repite

;************************************************************************************ ;**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

;**Decrementa parte baja y alta del periodo 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

Análisis del código

En primer lugar configuramos el registro T1CON.

Registro T1CON

T1CON=0x01

--- --- T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON

0 0 0 0 0 0 0 1

Bit 7 Bit 0

Page 43: 6 El Módulo Temporizador PIC

43

Divisor de frecuencia del preescaler a 1/1,

T1CKPS1=0

T1CKPS0=0

TMR1ON=1, habilitación del Timer1

Programa principal. Este programa genera a través de la patita RC2, una señal oscilatoria. Se usa un

botón 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 comparación al mínimo (cero), limpia latch de CCP1, habilita

módulo CCP1 para modo de comparación; poniendo la salida en 1 al coincidir los valores, y limpia

bandera de interrupción,

CLRF CCPR1H ;inicializa periodo de comparación CLRF CCPR1L ;al mínimo (cero) CLRF CCP1CON ;limpia latch de CCP1 BSF CCP1CON,CCP1M3 ;Habilita modulo CCP1 para modo de comparación BCF CCP1CON,CCP1M0 ;pone salida en 1 al coincidir BCF PIR1,CCP1IF ;limpia bandera de interrupción.

obteniéndose en el Registro CCP1CON:

--- --- CCP1X CCP1Y CCP1M3 CCP1M2 CCP1M1 CCP1M0

0 0 1 0 0 0

Bit 7 Bit 0

configurado el Módulo CCP1 para modo comparación, 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 ;checa bandera (lazo de espera)

GOTO checa ;si no se ha activado espera BCF PIR1,CCP1IF ;si ya se activó, la limpia

Invierte el bit CCP1CON<0>, con la máscara 00000001 (0x01),

MOVLW 0x01 ;máscara

Page 44: 6 El Módulo Temporizador PIC

44

XORWF CCP1CON,1 ;conmuta la acción al coincidir próxima comparación.

obteniéndose en el Registro CCP1CON:

--- --- CCP1X CCP1Y CCP1M3 CCP1M2 CCP1M1 CCP1M0

0 0 1 0 0 1

Bit 7 Bit 0

configurado el Módulo CCP1 para modo comparación, 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 continuación limpia la cuenta del timer 1 y checa botón RB0; si está presionado incrementa el

periodo, si no se ha presionado checa botón RB1; si está presionado decrementa el periodo.

Repitiendo todo nuevamente,

GOTO checa ;repite

Subrutinas. Son dos, incre y decre:

incre, incrementa el periodo tanto parte baja y alta (16 bits)

decre, decrementa el periodo tanto parte baja y alta (16 bits)

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 cuestión

puede especificarse previamente como alguno de los siguientes:

• Cada transición de bajada

• Cada transición de subida

• Cada cuarta transición de subida

• Cada dieciseisava transición de subida

Además de que el valor de TMR1 es capturado, la bandera de solicitud de interrupción

CCP1IF es activada, la cual deberá ser limpiada por software para poder detectarla si se está

consultando por poleo.

El tipo de acción 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 leído 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 módulo CCP en modo de captura:

Page 45: 6 El Módulo Temporizador PIC

45

El preescalador del CCP

El valor el preescalador se configura mediante los bits CCP1M3:CCP1M0. Sin embargo,

al realizar un cambio en la configuración del preescalador se puede generar una interrupción

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).

Configuración del modo de captura

A continuación se hace un resumen de algunas consideraciones que se deberán 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 razón la patita RC2/CCP1 es configurada como salida, se deberá tener

en cuenta que una escritura al puerto C puede causar una condición 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 interrupción falsa. Esto debe ser evitado limpiando

la máscara de interrupción correspondiente (CCP1IE (PIE1<2>)) cuando se

realice un cambio de estos para evitar una interrupción falsa.

• Si se está manejando por poleo la bandera de solicitud de interrupción, se

deberá limpiar por software antes de un posible evento que la active, de lo

contrario no se notará la activación.

El valor del dato (N) de 16 bits capturado se puede convertir a segundos (T) de acuerdo a la

relación:

T = 4*N/Fosc M seg

O bien, como frecuencia:

F= 1/T= Fosc/4*N M Hertz.

Page 46: 6 El Módulo Temporizador PIC

46

Ejemplo 6

Medición de Periodo

En este programa hace uso del modo de captura para realizar la medición del periodo de

una señal oscilatoria. Para ello se configura el evento de captura para que ocurra cada vez

que la patita RC2/CCP1 detecte una subida en la señal oscilatoria de entrada. El valor

capturado se envía por el puerto serie para su despliegue

;**************************************************************** ;* Este programa mide el periodo de una señal oscilatoria en la * ;* patita RC2/CCP1. El valor de periodo capturado representa el * ;* número de ciclos Tcy por periodo y se envía 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 ; CLRF CCP1CON ;limpia latch de CCP1 BSF CCP1CON,CCP1M2 ;Habilita modulo CCP1 para modo de captura BSF CCP1CON,CCP1M0 ;en transición de subida BCF PIR1,CCP1IF ;limpia bandera de interrupcion.

checa BTFSS PIR1,CCP1IF ;checa bandera

GOTO checa ;si no se ha activado espera. Cuenta del periodo 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 envía por el puerto serie MOVF CCPR1L,W CALL envbyte MOVLW 0x0D ;envía separador CALL envia MOVLW 0x0A CALL envia GOTO checa ;repite

;*************************************************************** ; Subrutina que envía el byte en W por el puerto serie, separado ; en los códigos 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 ;máscara 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 código ASCII equivalente CALL envia ;lo envía por el puerto serie MOVF lsnib,W ;carga lsnib en W

Page 47: 6 El Módulo Temporizador PIC

47

CALL asc ;obtiene código ASCII equivalente CALL envia ;lo envía por el puerto serie RETURN

asc ADDWF PCL,1 ;Calcula el código 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 asíncrono) BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisión) 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 transmisión

GOTO esp ;si está ocupado espera BCF STATUS,RP0 ;regresa al banco 0 MOVWF TXREG ;envía 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 relación

T = 4*N/Fosc = (2,712673611*10-7) N seg.

O bien, como frecuencia: F= 1/T= 3686400 / N Hertz.

Observación. El programa debería leer sin problemas periodos entre Tmáx= 17,777 mseg

(Fmin = 56,25 hertz) y un Tmin=0,271µseg (Fmáx =3,6864 Mhz), sin embargo debido al

retardo de la rutina de transmisión del dato, (en la realidad el programa no puede detectar

ninguna transición de subida durante la transmisión del dato) el programa sólo puede

procesar correctamente la transición hasta una frecuencia Fmáx =160Hz (Tmin = 6,25 mseg).

Análisis del código

En primer lugar configuramos el registro T1CON y CCP1CON.

Registro T1CON

T1CON=0x01

--- --- T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON

0 0 0 0 0 0 0 1

Page 48: 6 El Módulo Temporizador PIC

48

Bit 7 Bit 0

Divisor de frecuencia del preescaler a 1/1,

T1CKPS1=0

T1CKPS0=0

TMR1CS=0, selección de la fuente de reloj a modo temporizador

TMR1ON=1, habilitación del Timer1

Registro CCP1CON:

--- --- CCP1X CCP1Y CCP1M3 CCP1M2 CCP1M1 CCP1M0

0 0 0 1 0 1

Bit 7 Bit 0

Configurado el Módulo CCP1 para modo captura por flanco ascendente en RCy/CCPx, como se muestra

en la siguiente figura:

CCP1M3=0

CCP1M2=1

CCP1M1=0

CCP1M0=1

Programa principal. Este programa mide el periodo de una señal oscilatoria en la patita RC2/CCP1.

El valor de periodo capturado representa el número de ciclos Tcy por periodo y se envía

continuamente por el puerto serie.

Checa bandera; si no se ha activado espera, si ya se activó la limpia, a continuación limpia la

cuenta del timer 1, copia la cuenta del Timer 1 capturado y lo envía por el puerto serie, luego

envía 0x0D y 0x0A.

Repitiendo todo nuevamente, GOTO checa ;repite

Subrutinas. Son tres, envbyte, initrans y envia:

envbyte, subrutina que envía el byte en W por el puerto serie, separado en los códigos 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 14.7456 MHZ.

envia, subrutina para enviar el byte guardado en W por el puerto serie.