Você está na página 1de 48

El Mdulo Temporizador

1. Descripcin General del Mdulo Temporizador (Timer)


Los PIC 16F87X poseen un mdulo para el manejo preciso y eficiente de operaciones que involucran tiempo o conteo. Este mdulo consta de: Tres contadores/temporizadores denominados TMR0, TMR1 y TMR2 Dos mdulos CCP (Captura, Comparacin y PWM (Modulacin de ancho de pulso) denominados CCP1 y CCP2 En la siguiente tabla se resumen las principales caractersticas de los mdulos mencionados: Mdulo Caractersticas
TMR0 es un Contador/Temporizador de 8 bits Leble y escribible Reloj interno o externo Seleccin de flanco activo en el reloj externo Preescalador de 8 bits programable Solicitud de interrupcin opcional en el desbordamiento (de FFh a 00h) TMR1 es un Contador/Temporizador de 16 bits Leble y escribible Reloj interno o externo Preescalador programable Solicitud de interrupcin opcional en el desbordamiento (de FFFFh a 0000h) Reinicializacin opcional desde los mdulos CCP TMR2 es un Temporizador de 8 bits Dispone de un registro de periodo de 8 bits (PR2) Leble y escribible Preescalador programable Postescalador programable Solicitud de interrupcin opcional al coincidir TMR2 y PR2 Posibilidad de generar impulsos al mdulo SSP (puerto serie sncrono) Modo de captura Modo de comparacin Modo PWM (modulacin de ancho de pulso)

TMR0

TMR1

TMR2

CCP1 y CCP2

1.1. El Mdulo del Timer 0


El Timer 0 es un contador/temporizador de 8 bits. El registro principal de este mdulo es TMR0 (01h, 101h). Este registro se incrementa continuamente a una frecuencia seleccionable manejada por un preescalador y el reloj interno Fosc/4 (modo temporizador) o bien, por un preescalador y una seal externa (modo contador). 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 prctica, 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:
2

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, en donde se indican los bits que afectan su operacin 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. - 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. - T0CKI es una seal generada por un posible circuito externo y aplicado al pin T0CKI.
3

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. El registro TMR0 como Temporizador. Se programa el bit T0CS a 0 y PSA a 1, obtenindose la configuracin de funcionamiento la que se representada en la siguiente figura.

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

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:

Cuando no se utiliza el preescaler, la entrada de reloj externa es igual a la salida del preescaler. Las sincronizacin 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 pequeo retardo de 20ns) y a nivel bajo por lo menos 2Tosc (y un retardo RC de 20ns).Ver las caractersticas elctricas del dispositivo deseado. En resumen, en el modo contador, la seal que controla los incrementos del registro TMR0 es una seal externa que proviene de la patita T0CKI. En la figura anterior se puede ver que este modo se selecciona poniendo el bit T0CS en alto. Se puede seleccionar la transicin que provoca los incrementos mediante el bit Timer0 Source Edge Select T0SE (OPTION_REG<4>), limpiando este bit se selecciona la transicin de subida, mientras que al ponerlo en alto se selecciona la de bajada.
5

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

El PRESCALER consiste en la prctica, 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 propsitos de cualquier aplicacin. Hay slo un preescaler disponible que est compartido y puede asignarse indistintamente al modul de Timerl y el al WDT. La asignacin del preescaler al Timer0 hace que no haya ningn 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 asignacin del preescaler y el rango del preescaler. Cuando se le asigna al mdulo 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 instruccin 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 mdulo seleccionable. Como se puede ver en la figura anterior, el preescalador est compartido entre el timer0 y el mdulo watchdog, sin embargo slo puede conectarse a uno de los dos y esto se establece mediante el bit PSA (OPTION_REG<3>), as, con este bit en alto el preescalador es asignado al reloj del watchdog, mientras que con un nivel bajo en PSA el preescalador dividir la frecuencia que maneja al timer 0. La seleccin del mdulo (valor de divisin de frecuencia) del preescalador se puede realizar mediante los bits PS2,PS1,PS0 (OPTION_REG<2:0>) de acuerdo a la siguiente tabla:
PS2 PS1 PS0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 Divisor (timer 0) 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

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. Observacin: Cuando el preescalador est asignado al timer 0, cualquier escritura al registro TMR0 (cualquier BCF, BSF, MOVWF, CLRF, etc) limpiar el preescalador. En forma similar, cuando est asignado al watchdog, una instruccin CLRWDT limpiar no solo el timer del watchdog, sino tambin el preescalador. A manera de resumen se presenta a continuacin una descripcin de los bits del registro OPTION_REG que tienen relacin con el timer 0:
7

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). 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. PSA.- Bit de asignacin del preescalador. Un 1 en este bit asigna el preescalador al watchdog y un 0 lo asigna al Timer0.

bit 4

bit 3

bits 2:0 PS2:PS0.- Bits de seleccin del valor del preescaler (ver tabla anterior). TABLA DE REGISTROS ASOCIADOS AL TIMER0
Direccin 0bh, 8Bh 10Bh,18Bh 81h,181h 85h Nombre Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Valor en POR,BOR 0000 000x 1111 1111 --11 1111 Valor en el resto de Reset 0000 000x 1111 1111 --11 1111

INTCON OPTION_REG TRISA

GIE RBPU ---

PEIE INTEDG ---

T0IE T0CS

INTE T0SE

RBIE PSA

T0IF PS2

INTF PS1

RBIF PS0

Registro de direccionamiento de datos del PORTA

Leyenda: x = desconocido, u = inalterado; - = no implementado se lee como 0. Las celdas sombreadas no son usadas por el TIMER0

1.2. El Mdulo 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 lebles como escribibles. Al par de registros TMR1H:TMR1L los denominaremos por comodidad como si fueran un solo registro de 16 bits (TMR1). As, el registro TMR1 se incrementa de 0000h a FFFFh y en la siguiente cuenta se reinicia en 0000h y as sucesivamente, al reciclarse se activa (en alto) la bandera TMR1IF (PIR1<0>), la cual puede ser utilizada para generar una interrupcin, o bien, para ser consultada por poleo, teniendo las mismas precauciones que ya se explicaron antes para la bandera T0IF. En la siguiente figura se muestra un diagrama de bloques de este mdulo, en donde se indican los bits que afectan su operacin y la manera en que lo hacen.

Nota 1: Cuando el bit T10SCEN est desactivado, el invertir est apagado. Esto elimina el gasto de energa 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 estos apuntes no se describe este modo. 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.

Nota. Las flechas indican los incrementos del contador.


9

Modo de funcionamiento del Timer1 como Contador Sncrono 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 seal 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 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. 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 continua 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 (Seccin 6.5.1). Cuando se trabaja en el modo contador asncrono, el TIMER1 no puede usare como base de tiempos para el mdulo CCP (Captura y comparacin-PWM). Lectura y escritura en el TIMER1 cuando se trabaja en el modo contador asncrono Se pueden leer los contadores TMR1H y TMR1L mientras la seal 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 idntico 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 seleccin de los condensadores para el oscilador del TIMER1

10

Tipo de Oscilador
LP

Frecuencia

C1

C2
33pF 15 pF 15 pF 20 PPM 20 PPM 20 PPM

32.768 100 kHz 200 kHz

32 kHz 33pF 100kHz 15 pF 200 15 pF Estos valores son para los siguientes cristales de referencia EpsonC-001R21.768K-A Epson C-2 100.000 KC-p1 STD XTL 200.000 kHz

Notas: 1. Capacidades mayores aumentan la estabilidad del oscilador, pero tambin aumentan el start-up. 2. Cada cirstal/resonador tiene sus propias caractersticas, el usuario debe consultar los valores apropiados de los componentes externos al cristal.

RESTABLECIMIENTO DEL TIMER1 UTILIZADO LA SALIDA TRIGGER DEL CCP Si el mdulo CCPI o CCP2 se configuran en modo comparacin para generar un disparo por evento especial (CCP1M3:CCP1MO = 1011), esta seal reestablecer el TIMIER1. Nota. El evento especial que activa los mdulos CCP1 y CCP2 no activar el flag TMR1IF (PIR1<0>). El TIMER1 debe configurarse como temporizador o contador sncrono Restablecimiento TIMER1 que usa un disparador de CCP TIMER1 debe configurarse para temporizador o contador sncrono para aprovechar esta caracterstica. Si el TIMER1 est trabajando en modo contador asncrono, 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 despus 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 despus de un Power-on Reset o Brown-out Reset que deja a 1:1 el preescaler. En los dems reset, el registro no es alterado. El contador del preescaler se pone a cero al escribir en los registros TMR1H o TMR1L.

11

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

bits 5:4 T1CKPS1:T1CKPS0.- Bits de seleccin 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 Observacin: La cuenta interna del preescalador es limpiada cuando se hace una escritura a cualquiera de los registros TMR1H o TMR1L bit 1 TMR1CS.- Bit de seleccin de la fuente de reloj 1 = Modo contador (fuente de reloj: patita RC0/T1OSO/T1CKI) 0 = Modo Temporizador (fuente de reloj Fosc/4) TMR1ON.- Bit de habilitacin / deshabilitacin del Timer 1: 1 = habilita Timer 1 0 = Deshabilita Timer 1

bit 0

Modos de trabajo del TIMER1 EL TIMERl tiene los siguientes modos de trabajo: 1. Como Temporizador 2. Como contador Sncrono 3. Como contador Asncrono El modo de trabajo viene determinado la fuente de los impulsos de reloj, es decir, la seal 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 travs del pin RC0/TlCKl. Adems como se ver ms adelante el TIMER1 tiene la posibilidad de reinicializarse, a partir del mdulo CCP.
12

REGISTRO T1CON: Registro de control del TIMER1 (direccin 10h) U-0 --Bit 7 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 0

bit 7-6: No implementados: Se lee como 0 bit 5-4: TlCKPS1:T1CKPS0: bit de seleccin del preescaler de la seal 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 habilitacin 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. Nota. El oscilador y la resistencia de 1 = Habilita el oscilador desconectan para reducir el consumo 0 = Deshabilita el oscilador #TlSYNC: bit de control de sincronizacin de la seal 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 condicin se ignora. El TIMER1 utiliza el reloj interno cuando TMRICS=0 bit 1: TMR1CS: bit de seleccin 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 distribucin de los bits.

bit 2:

13

Direccin 0Bh,8Bh 10Bh,18Bh 0Ch 0Bh 0Eh 0Fh 10h

Nombre INTCON PIR1 PIE1 TMR1L TMR1H T1CON

Bit 7 GIE PSPIF PSPIE

Bit 6 PEIE ADIF ADIE

Bit 5 T0IE RCIF RCIE

Bit 4 INTE TXIF TXIE

Bit 3 RBIE SSPIF SSPIE

Bit 2 TOIF CCP1IF CCP1IE

Bit 1 INTE TMR2IF TMR2IE

Bit 0 RBIF TMR1IF TMR1IE

Valor en POR,BOR 0000 000x 0000 0000 0000 0000 xxxx xxxx xxxx xxxx

Valor en el resto de Reset 0000 000u 0000 0000 0000 0000 uuuu uuuu uuuu uuuu --uu uuuu

Registro de carga del byte de menor peso del registro de 16 bits de TMR1 ----T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON

--xx xxxx

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 estn reservados para el PIC16F873/876, mantener estos bit a cero.

1.3. El Mdulo del Timer 2


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

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 comparacin o de Periodo En operacin, el contenido del registro TMR2 se compara continuamente con un registro de periodo denominado PR2 (92h) cuyo valor podemos establecer por software. Cada vez que la cuenta de TMR2 es igual a PR2, se reinicia el conteo en TMR2 desde cero, y adems se genera una seal de salida, la cual es tratada por un postescalador, para poder generar una seal TMR2IF (PIR1<1>) que puede ser usada para solicitar una interrupcin,
14

o para ser leda por poleo. c. El Postescalador El postescalador divide la frecuencia con que ocurre una activacin de la bandera TMR2IF, es decir, si el valor del postescalador es 1/1, esta bandera se activar cada vez que TMR2 se reinicie, en cambio, si es 1/16 (por ejemplo), TMR2IF se activar cada 16 reinicios de TMR2. En forma similar a los otros dos Timers, esta bandera debe ser limpiada previamente, si se quiere detectar su activacin, esto puede ser hecho en la rutina de atencin a la interrupcin, o bien en la rutina que la detecta por poleo. El valor de divisin del postescalador puede establecerse por software mediante los bits T2OUPS3:T2OUPS0 (T2CON<6:3>). A continuacin se describe el principal registro relacionado con el Timer 2 y todos sus bits.

bits 6:3 T2OUPS3:T2OUPS0.- Bits de seleccin del valor del divisor de frecuencia del postescalador, de acuerdo a la siguiente tabla: 0 0 0 0 = divisor 1/1 0 0 0 1 = divisor 1/2 1 1 1 1 = divisor 1/116 Observacin: La cuenta interna del postescalador y el preescalador es limpiada cuando ocurre cualquiera de los siguientes eventos: Una escritura a alguno de los registros TMR2 o T2CON o bien, un Reset del sistema de cualquier tipo (POR, MCLR, WDT, o BOR). bit 2 TMR2ON.- Bit de encendido del Timer 2 1 = Enciende (energiza) el Timer 2 0 = Apaga (desconecta) el Timer 2

bits 1:0 T2CKPS1:T2CKPS0.- Bits de configuracin del valor del preescalador de acuerdo a la siguiente tabla: 0 0 = divisor 1/1 0 1 = divisor 1/4 1 x = divisor 1/16 Operaciones con el TIMER2 El Timer2 tiene emparejado el registro PR2 que ocupa la posicin 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>).
15

El registro PR2 es un registro de 8 bits que puede ser escrito y ledo, este registro toma el valor FF despus de un Reset. El postscaler permite dividir la seal 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 (direccin 12h)
U-0 --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 7:

No implementado: Se lee como 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 1101 = Divisor del postescaler 1:14 1110 = Divisor del postescaler 1:15 1111 = Divisor del postescaler 1:16 bit 2: TMR2ON: bit de activacin del TIMER2 1:= habilita el funcionamiento del TIMER2 0 = Inhibe el funcionamiento del TIMER2

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 16

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 posicin 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 interrupcin si se pone a 1 el bit TMR2IE (<1> PIE1) Salida del TMR2 La salida de TMR2 (antes del postscaler) alimenta al Mdulo de SSP que opcional mente puede usarse para generar la seal de reloj de desplazamiento.

REGISTROS ASOCIADOS AL TMR2


Valor en POR,BOR

Direccin 0Bh,8Bh 10Bh, 18Bh 0Ch 0Bh 11h 12h 92h

Nombre

Bit 7

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

Valor en el resto de Reset


0000 000u 0000 0000 0000 0000 0000 0000 -000 0000 1111 1111

INTCON PIR1 PIE1 TMR2 T2CON PR2

GIE PSPIF PSPIE ---

PEIE ADIF ADIE TOUTPS3

TOIE RCIF RCIE TOUPS2

INTE TXIF TXIE TOUPS1

TOIF SSPIF SSPIE TOUPS0

RBIE CCP1IF CCP1IE TMR2ON

INTE TMR2IF TMR2IE T2CKPS1

RBIF TMR1IF TMR1IE T2CKPS0

0000 000x 0000 0000 0000 0000 0000 0000 -000 000 1111 1111

Mdulo Del registro Timer2 Registro de perodo del TMR2

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 estn 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 nmero de veces que produce una transicin de bajo a alto en la patita T0CKI. El valor del contador se incrementar una vez por cada dos transiciones y ser enviado a travs del puerto serie para ser desplegado en la pantalla de una PC.
17

;**************************************************************************** ;* 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" inic org 0x0000 CALL initrans BCF STATUS,RP0 CLRF TMR0 BSF STATUS,RP0 MOVLW 0xE0 MOVWF OPTION_REG BCF STATUS,RP0 ciclo MOVF TMR0,W CALL Envbyte MOVLW 0x0D CALL envia MOVLW 0x0A CALL envia GOTO ciclo ;inicializa el puerto serie para transmisin ;Banco 0 ;inicializa la cuenta de TMR0 ;Banco 1 ;dato de configuracin para el timer0 ;configura modo contador, transicin positiva, ;preescalador 1/2 asignado a timer0 ;Banco 0 ;lee cuenta actual ;enva el valor por el puerto serie ;carga carcter <CR> ;lo enva ;carga carcter <LF> ;lo enva ;repite

;*************************************************************** ; Subrutina que enva el byte en W por el puerto serie, separado ; en los cdigos ASCII de sus dos nibbles hexadecimales ;*************************************************************** 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 ADDWF PCL,1 ;carga msnib en W ;obtiene cdigo ASCII equivalente ;lo enva por el puerto serie ;carga lsnib en W ;obtiene cdigo ASCII equivalente ;lo enva por el puerto serie

;Calcula el cdigo a retornar ;Saltando W instrucciones adelante DT "0123456789ABCDEF"

;**************************************************************** ;Subrutina para inicializar el puerto serie USART como transmisor ;a 9600 Bauds, considerando un cristal de reloj de 14.7456 MHZ ;**************************************************************** initrans: BCF STATUS,RP1 BSF STATUS,RP0 ;banco 1 BCF TXSTA,BRGH ;pone bit BRGH=0 (velocidad baja) MOVLW 0x17 ;valor para 9600 Bauds (Fosc=14.7456 Mhz) MOVWF SPBRG ;configura 9600 Bauds BCF TXSTA,SYNC ;limpia bit SYNC (modo asncrono) BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisin) BCF STATUS,RP0 ;regresa al banco 0 BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie) RETURN

18

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

Observacin. Mediante el programa anterior podemos realizar el conteo de pares de rebotes provocados por un botn pulsador, basta con conectar la salida de dicho botn a la patita T0CKI. Al hacer lo anterior se ver que por cada pulsacin del botn se incrementa la cuenta no de uno en uno, sino en un valor mayor por el efecto de los rebotes. Esto tambin quiere decir, que si no deseamos que el contador se vea afectado por el rebote de la seal a contar, se deber incluir un limpiador de rebotes por hardware, externo al PIC. Anlisis del cdigo
En primer lugar configuramos el registro OPTION_REC. Registro OPTION_REC OPTION_REC = E0 #RBPU 1 Bit 7 INTEDG 1 T0CS 1 T0SE 0 PSA 0 PS2 0 PS1 0 PS0 0 Bit 0

T0CS = 1, Seleccionado como reloj la patita T0CKI (modo contador) T0SE = 0, El incremento de TMR0 en la transicin de bajo a alto de T0CKI PSA = 0, Asigna el preescalador al Timer0. PS2=0, PS1=0 y PS0=0; Bits de seleccin del valor del preescaler a 1/2 Programa principal. Este programa lee el valor de la cuenta actual de TMR0, enva el valor por el puerto serie, luego carga el carcter <CR> y lo enva, y tambin carga el carcter <LF> y lo enva. Subrutinas. Son tres: Envbyte, initrans y envia: Envbyte. Subrutina que enva el byte W por el puerto serie, separados en los cdigos 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 grficos. msnib 19

Bit 7 lsnib

Bit 0

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 mxima duracin, la cual se intercala en el encendido/apagado de un LED conectado a la patita RC0, es decir, el LED parpadear a la frecuencia F que se puede calcular como sigue: F = 1/(TH+TL) En donde TH es el tiempo de encendido y TL es el tiempo de apagado del LED. Como en el ejemplo son iguales, usaremos slo T = TH = TL, por lo tanto F = 1/(2T) 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 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.
20

Es decir, TH = Tciclo = N*M*(4/Fosc) Fciclo = Fosc/4 * 1/M * 1/N donde: Fosc/4, Frecuencia de oscilacin (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 * ;* duracin (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 BSF STATUS,RP0 BCF TRISC,0 BCF STATUS,RP0 BSF PORTC,0 CALL pausa BCF PORTC,0 CALL pausa GOTO rep

inic rep

;Banco1 ;patita RC0 como salida ;Banco 0 ;enciende LED ;pausa de 17.77 mseg ;apaga LED ;pausa de 17.77 mseg

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

Anlisis del cdigo


En primer lugar configuramos el registro OPTION_REC. Registro OPTION_REC 21

OPTION_REC = C7 RBPU# 1 Bit 7 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 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. Observacin. La rutina de pausa se puede modificar para una duracin 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 clculo de cualquier tiempo
tiempo = Tciclo * Mz

donde: Tciclo, Duracin del ciclo 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

22

El valor de Mz siempre debe ser un valor entero. El cdigo para la subrutina de 1seg, ser:
Count delay RES 1 ;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 movlw movwf decfsz goto return 6 TMR0 Count,1 DelayLoop

;No, espera... ;Si, reinicializa TMR0 a 6 ;cuenta 125 cruces por cero

Nota: Para un reloj de 4 Mhz, una duracin mxima M = 256, N = 256 tendremos: Tciclo = N*M*(4/Fosc) Tciclo = TMAX = 256*256* (4/Fosc) Tciclo = TMAX = 65,536 mseg Ejemplo Prctico Realizar un intermitente con cuatro leds cuya frecuencia de intermitencia con un retardo igual a un segundo utilizando el registro TMR0. El cdigo de este ejemplo est disponible en SEQTMR0.ASM y se muestra a continuacin:
;************************************************** ; ; SEQTMR0.ASM ; ;************************************************** PROCESSOR RADIX INCLUDE 16F877 DEC "P16F877.INC"

;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer

23

;Enable power up timer ;Disable code protect

__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF


ORG Count Shift RES RES 20H 1 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 movwf 11110000B TRISB

;Asigna el PRESCALER a TMR0 en la configuracion a 1:32 movlw movwf 00000100B 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 movwf 00000001B 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 movwf Shift,W PORTB

;Para encender las luces debe utilizar la instruccin 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 razn, antes de la instruccin RLF borrar el bit ;de acarreo de la instruccin ;bcf STATUS,C. bcf rlf STATUS,C 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 ejecucin de este bucle?: ; ; 00000001 <--- Valor inicial (primer led de acceso)

24

; 00000010 rlf ; 00000100 rlf ; 00001000 rlf ; 00010000 rlf En este momento se ejecuta la instruccin swapf ;obteniendo: ; 00000001 ... por lo que forma btfsc swapf Shift,4 Shift,F

;Introducir un retraso entre el encendido y el otro call Delay

; Volver a ejecutar el bucle goto MainLoop

;************** ; Subrutinas ;************** ;Insercin 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 movwf 6 TMR0

;El registro de la cuenta se inicializa a 125 debido a su ;propsito y salir del bucle movlw movwf 125 Count

;Lazo de contar DelayLoop ;TMR0 vale 0 ? movf btfss goto movlw movwf TMR0,W STATUS,Z DelayLoop 6 TMR0

;No, espera... ;Si, TMR0 reinicia y comprueba si ;ha pasado 125 veces por cero

25

decfsz goto return END

Count,1 DelayLoop

Anlisis del cdigo SEQTMR0.ASM En primer lugar programar el PRESCALER para obtener una frecuencia de conteo apropiada, insertando las siguientes instrucciones al inicio del programa:
movlw movwf 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 7.
RBU 0 INTDEG 0 T0CS 0 T0SE 0 PSA 0 PS2 1 PS1 0 PS0 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 movwf 6 TMR0 125 Count

y
movlw movwf

Las primeras dos almacenan en TMR0 el valor 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.
26

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 16, en el cual se utiliza el Timer 1 para realizar una pausa de mxima duracin, la cual se intercala en el encendido / apagado de un LED conectado a la patita RC0, es decir, el LED parpadear a la frecuencia F que se puede calcular como sigue: F = 1/(TH+TL) En donde TH es el tiempo de encendido y TL es el tiempo de apagado del LED. Como en el ejemplo son iguales, usaremos slo T = TH = TL, por lo tanto F = 1/(2T) Para calcular T con una frecuencia de reloj Fosc dada y un valor del preescalador 1/M, para un ciclo de N incrementos del registro TMR1 tendremos que la duracin (Tciclo) del ciclo ser: T = Tciclo = N*M*(4/Fosc) As, para una duracin mxima M = 8, N = 65536 tendremos: TMAX = 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 * ;* duracin (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 rep BSF STATUS,RP0 BCF TRISC,0 BCF STATUS,RP0 BSF PORTC,0 CALL pausa ;pausa BCF PORTC,0 CALL pausa ;pausa ;Banco1 ;patita RC0 como salida ;Banco 0 ;enciende LED de 71.11 mseg ;apaga LED de 71.11 mseg

27

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

Observacin 1: El programa es idntico 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 Observacin 2: La rutina de pausa se puede adaptar para una duracin 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 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
28

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:

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

29

ciclo BTFSS PIR1,TMR1IF GOTO ciclo decfsz Mz,1 goto Delay15s return ;checa bandera de sobre flujo (cuenta=65536) ;si no, se ha activado, espera

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 15 y 16 de dejar pasar el tiempo transcurrido en una sla activacin de TMR2IF?. 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, tendremos que la duracin de la pausa dada por Tciclo = N*M*P*(4/Fosc) As, para una duracin mxima 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.

30

1.4. Los Mdulos de CCP (Captura / Comparacin / PWM)


El PIC16F87X posee dos mdulos CCP, denominados CCP1 y CCP2. Ambos mdulos son prcticamente idnticos con la excepcin de la operacin del disparo de evento especial. Cada uno de estos dos mdulos poseen un registro de 16 bits, el cual puede operar como: Registro de captura de 16 bits Registro de comparacin de 16 bits Registro de Ciclo de Trabajo del mdulo PWM de 8 bits. Cada modo de operacin requiere como recurso uno de los siguiente tabla se muestran los timers usados por cada modo: Modo de operacin del CCP
Captura Comparacin PWM

timers del PIC. En la

Recurso utilizado
Timer 1 Timer 1 Timer 2

A continuacin se da un breve resumen de los registros relacionados con cada mdulo: a. El Mdulo CCP1 El registro principal de este mdulo (CCPR1) se compone de dos registros de 8 bits, denominados CCPR1H (16h) (parte ms significativa) y CCPR1L (15h) (parte menos significativa). La operacin del mdulo se controla mediante el registro CCP1CON y el disparo de evento especial, el cual es generado al alcanzarse la igualdad en un registro de comparacin resetear el Timer 1. b. El Mdulo CCP2 El registro principal de este mdulo (CCPR2) se compone de dos registros de 8 bits, denominados CCPR2H (parte ms significativa) y CCPR2L (parte menos significativa). La operacin del mdulo se controla mediante el registro CCP2CON y el disparo de evento especial, el cual es generado al alcanzarse la igualdad en un registro de comparacin resetear el Timer 1, e iniciar una conversin analgico/digital (si el mdulo convertidor A/D est habilitado). Esta ltima caracterstica es la diferencia entre los dos mdulos. Seleccin del modo de operacin La seleccin del modo en que trabajara el mdulo CCPx se realiza mediante los cuatro bits menos significativos del registro CCPxCON, es decir, mediante los bits CCPxM3:CCPx0 (CCPxCON<3:0>) de acuerdo a la siguiente tabla
CCPxM3:CCPxM0 0000 0100 0101 Modo seleccionado Captura/Comparacin/PWM deshabilitados Captura cada transicin de bajada Captura cada transicin de subida

31

0110 0111 1000 1001 1010 1011 11xx

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

A continuacin se describe a detalle cada uno de los modos de operacin, comenzando con el modo PWM. La descripcin se realiza slo para el mdulo CCP1, ya que es prcticamente igual al CCP2.
INTERACCIN DE LOS DOS MDULOS CCP Modo CCPx Captura Captura Comparacin PWM PWM PWM Modo CCPy Captura Comparacin Comparacin 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

Registro CCP1CON (direccin 17h)/Registro CCP2CON (direccin 1Dh)


U-0 --Bit 7 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 7-6: No implementados: Se lee como "0" bit 5-4: CCPxX: CCPxY: bit menos significativos de PWM Modo Captura sin usar Modo Comparacin sin usar Modo PWM: Estos dos bit son los menos significativos del ciclo de PWM. Los ocho bits ms significativos se encuentran en CCPRXL.

bit 3-0:CCPxM3-.CCPxM0; bit de seleccin del modo de trabajo del mdulo comparador CCPX.
CCPxM3: CCPxM0 0000 0100 0101 0110 0111 MDO DE TRABAJO DEL MDULO Mdulo Caputa/Comparacin/PWM desactivado (reset del mdulo CCPx) Modo de captura por flanco descendente RCy/CCP Modo de captura por flanco ascendente en RCy/CCPx Modo de captura, cada 4 flancos ascendentes en RCy/CCPx Mdo apturador. Cada 16 flancos ascendentes en RCy/CCPx 32

1000 1001 1010 1011

11xx

Modo comparacin, activa la patilla, se pone a 1 RCy/CCPx al coincidir los valores (el bit CCPxIF se pone a uno) Modo de comparacin se pone a 0 la patilla RC/CCPx al coincidir los valores (el bit CCPxIF se pone a uno) Modo de comparacin, genera una interrupcin sofware (el bit CCPxIF se pone a 1, el pin de CCPx no es afectado) Modo de comparacin, en el que se produce un disparo especial para cada mdulo (el bit CCPxIF se pone a uno, el pin CCPx no es afectado); CCP1 resetea TMR1; CCP2 resetea TMR1 y comienza una conversin de A/D (si el mdulo de A/D se habilita) Modo de PWM

1. Modo PWM (Modulacin de Ancho de Pulso) En este modo se puede producir una salida de frecuencia fija seleccionable modulada en ancho de pulso (o ciclo de trabajo) con una resolucin de 10 bits, a travs de la patita RC2/CCP1, como se muestra en la figura siguiente:

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.

33

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 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 bits ms significativos (msb)) y los dos bits menos significativos (lsb) a CCP1CON<5:4> este valor de 10 bits lo representaremos como
34

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 internos) alcanza el valor de CCPR1H (concatenado con dos bits internos tambin) 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 deseamos 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 por: PeriodoPWM = (PR2+1)*4*TOSC*M Despejando PR2 ser:
35

PR2= (PeriodoPWM / (4*TOSC*M)) 1 Pero si se desea tener el PeriodoPWM mximo se sustituye, PR2=255 = FFh (valor mximo): 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 10

4 FFh 10

1 FFh 10

1 3Fh 8

1 1Fh 7

1 17h 5.5

c. Secuencia de configuracin del PWM A continuacin se resumen los pasos para realizar la configuracin inicial del PWM: 1. Establecer el periodo del PWM escribiendo al registro PR2. 2. Establecer el Ciclo de Trabajo del PWM escribiendo al registro CCPR1L y a los bits CCP1CON<5:4>. 3. Configurar como salida la patita CCP1, limpiando el bit TRISC<2>. 4. Configurar el preescalador del Timer 2 y habilitar el Timer 2, escribiendo al registro T2CON. 5. Configurar el mdulo CCP1 para operacin PWM. Poniendo en alto los bits CCP1CON <3:2>. A continuacin se ilustra este proceso de configuracin en el siguiente ejemplo. 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:

36

Eleccin de la frecuencia de operacin del PWM: Como la carga que se desea controlar es de tipo resistivo, no tendr limitaciones respecto a frecuencias altas de operacin, salvo las limitaciones de baja frecuencia que le impone la respuesta trmica para que el parpadeo no sea visible, es decir, se puede usar desde una frecuencia lenta (del orden de unos 20 hertz) hasta frecuencias tan altas como el PWM pueda soportar (del orden de los kilohertz). Para usar los 10 bits de resolucin, repetimos el clculo del ejemplo anterior, pero ahora supondremos una FOSC = 14,7456 Mhz, es decir, TOSC = 0,06781684 seg, entonces, el ciclo de trabajo mximo posible ser (para M=1): TPWM = (2 r)* TOSC*M, r = 10 = 1024*0,06781684x10-6 = 0,069444 mseg (CT mximo)

TPWM

Y para lograr esto, se necesita: PR2= (PeriodoPWM / (4*TOSC*M)) 1, El PeriodoPWM mximo se tendr sustituyendo, PR2=255 = FFh. (valor mximo) 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 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. *

37

;* 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 operacin PWM BSF CCP1CON,CCP1M2

;en este punto la salida PWM tiene un Ciclo de trabajo CT=0 CLRF CTL ;inicializa CT de 10 bits en cero CLRF CTH Esp0 BTFSC PORTB,0 ;Checa Botn RB0 CALL incre ;si est presionado incrementa CT Esp1 BTFSC PORTB,1 ;si no se ha presionado Checa botn RB1 CALL decre ;si est presionado Decrementa CT MOVF CTL,W ;si no se ha presionado obtiene copia de CT parte baja MOVWF CCPR1L ;actualiza parte baja del CT real ;**** a continuacin actualiza la parte alta del CT real MOVLW 0xCF ;mscara ANDWF CCP1CON,1 ;limpia los dos msbits del CT real MOVLW 0x03 ;mscara ANDWF CTH,1 ;limpia los 6 bits altos en CTH SWAPF CTH,W ;copia los 2 bits bajos de CTH en el nibble alto de W IORWF CCP1CON,1 ;pone bits que deben ser 1 en los dos msb del CT real ;**** con esto queda actualizada la parte alta del CT real CALL pau GOTO Esp0 ;pausa para moderar la velocidad de incremento/decremento ;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

38

GOTO p1 DECFSZ cont1,1 GOTO p1 RETURN END

Anlisis del cdigo


En primer lugar configuramos los registros CCPR1L, CCP1CON y T2CON. Registro CCPR1L 0 Bit 7 0 0 0 0 0 0 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 --Bit 7 --CCP1X 0 CCP1Y 0 CCP1M3 1 CCP1M2 1 CCP1M1 0 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

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 39

(CTH:CTL), inicializa CT de 10 bits en cero. Luego checa Botn RB0; si est presionado incrementa CT, si no se ha presionado checa botn RB1; si est presionado decrementa CT, si no se ha presionado actualiza parte baja del CT real. A continuacin 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 mscara 11001111 (0xCF),
MOVLW 0xCF ANDWF CCP1CON,1 ;mscara ;limpia los dos msbits del CT real

Limpia los seis bits altos en CTH= 000000YY, con la mscara 00000011 (0x03),
MOVLW 0x03 ANDWF CTH,1 ;mscara ;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 ms 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 comparacin el registro de 16 bits CCPR1 (CCPR1H:CCPR1L) se compara constantemente con el valor del registro de 16 bits TMR1. De manera que cuando sus valores coinciden adems de activarse la bandera para solicitar interrupcin CCP1IF (PIR1<2>), puede ocurrir en la patita RC2/CCP1 (previa configuracin) alguna de las siguientes acciones: RC2/CCP1 Se pone en alto RC2/CCP1 Se pone en Bajo
40

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

Configuracin del modo de comparacin A continuacin se hace un resumen de algunas consideraciones que se debern hacer para configurar adecuadamente el modo de comparacin: la patita RC2/CCP1 deber configurarse como salida limpiando el bit TRISC<2>. Al limpiar el registro CCP1CON el latch de salida de la patita RC2/CCP1 se forza a su valor default de cero. El Timer 1 debe estar corriendo en modo temporizador (o en modo contador sincronizado) Si se est manejando por poleo la bandera de solicitud de interrupcin, se deber limpiar por software antes de un posible evento que la active, de lo contrario no se notar la activacin. 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 comparacin para realizar la conmutacin de una seal cada vez que transcurre un tiempo, el cual se ajusta al oprimir un botn de incremento o uno de decremento. El hardware utilizado es similar al del ejemplo anterior, slo que la salida en lugar de manejar una lmpara, se puede simplemente monitorear mediante un zumbador piezoelctrico, o visualizarla en un osciloscopio.
;************************************************************** ;* Este programa genera a travs de la patita RC2, una seal * ;* oscilatoria. Se usa un botn conectado a RB0 para incremen-* ;* tar el periodo y otro conectado a RB1 para disminuirlo. * ;* Se supone un cristal de 14.7456 Mhz *

41

;************************************************************** 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 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. checa BTFSS PIR1,CCP1IF GOTO checa BCF PIR1,CCP1IF MOVLW 0x01 XORWF CCP1CON,1 CLRF TMR1L CLRF TMR1H BTFSC PORTB,0 CALL incre BTFSC PORTB,1 CALL decre GOTO checa ;checa bandera (lazo de espera) ;si no se ha activado espera ;si ya se activ, la limpia ;mscara ;conmuta la accin al coincidir prxima comparacin. ;limpia la cuenta del timer 1 ;Checa Botn RB0 ;si est presionado incrementa periodo ;si no se ha presionado Checa botn RB1 ;si est presionado decrementa periodo ;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

Anlisis del cdigo


En primer lugar configuramos el registro T1CON. Registro T1CON T1CON=0x01 --0 Bit 7 --0 T1CKPS1 0 T1CKPS0 0 T1OSCEN 0 T1SYNC 0 TMR1CS 0 TMR1ON 1 Bit 0 42

Divisor de frecuencia del preescaler a 1/1, T1CKPS1=0 T1CKPS0=0 TMR1ON=1, habilitacin del Timer1 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.

obtenindose en el Registro CCP1CON: --Bit 7 --CCP1X 0 CCP1Y 0 CCP1M3 1 CCP1M2 0 CCP1M1 0 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 ;checa bandera (lazo de espera) ;si no se ha activado espera ;si ya se activ, la limpia

Invierte el bit CCP1CON<0>, con la mscara 00000001 (0x01),


MOVLW 0x01 ;mscara

43

XORWF CCP1CON,1

;conmuta la accin al coincidir prxima comparacin.

obtenindose en el Registro CCP1CON: --Bit 7 --CCP1X 0 CCP1Y 0 CCP1M3 1 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

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 cuestin puede especificarse previamente como alguno de los siguientes: Cada transicin de bajada Cada transicin de subida Cada cuarta transicin de subida Cada dieciseisava transicin de subida

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

El preescalador del CCP

El valor el preescalador se configura mediante los bits CCP1M3:CCP1M0. Sin embargo, al realizar un cambio en la configuracin del preescalador se puede generar una interrupcin falsa, para evitar lo anterior se deber apagar el modulo CCP (limpiando el registro CCP1CON) previamente al cambio de valor del preescalador. Este preescalador es independiente al preescalador del Timer 1 (el cual puede usarse como ya se explic con sus posibles divisores de 1/1, 1/2, 1/4, 18). Configuracin del modo de captura A continuacin se hace un resumen de algunas consideraciones que se debern hacer para configurar adecuadamente el modo de captura: En el modo de captura la patita RC2/CCP1 deber configurarse como entrada poniendo en alto el bit TRISC<2>. Si por alguna razn la patita RC2/CCP1 es configurada como salida, se deber tener en cuenta que una escritura al puerto C puede causar una condicin de captura. El Timer 1 debe estar corriendo en modo temporizador (o en modo contador sincronizado), de lo contrario el modo de captura puede no funcionar. Cuando se realiza un cambio de un modo de captura a otro modo de captura se puede generar una solicitud de interrupcin falsa. Esto debe ser evitado limpiando la mscara de interrupcin correspondiente (CCP1IE (PIE1<2>)) cuando se realice un cambio de estos para evitar una interrupcin falsa. Si se est manejando por poleo la bandera de solicitud de interrupcin, se deber limpiar por software antes de un posible evento que la active, de lo contrario no se notar la activacin. El valor del dato (N) de 16 bits capturado se puede convertir a segundos (T) de acuerdo a la relacin: T = 4*N/Fosc M seg O bien, como frecuencia: F= 1/T= Fosc/4*N M Hertz.
45

Ejemplo 6 Medicin de Periodo En este programa hace uso del modo de captura para realizar la medicin del periodo de una seal oscilatoria. Para ello se configura el evento de captura para que ocurra cada vez que la patita RC2/CCP1 detecte una subida en la seal oscilatoria de entrada. El valor capturado se enva por el puerto serie para su despliegue
;**************************************************************** ;* Este programa mide el periodo de una seal oscilatoria en la * ;* patita RC2/CCP1. El valor de periodo capturado representa el * ;* nmero de ciclos Tcy por periodo y se enva continuamente por* ;* el puerto serie. Se supone un cristal de 14.7456 Mhz * ;**************************************************************** Include "p16f877.inc" org 0x0000 msnib EQU 0x20 lsnib EQU 0x21 Inic CALL initrans ;inicializa puerto serie como transmisor BSF STATUS,RP0 ;Banco1 BSF TRISC,2 ;patita RC2/CCP1 como entrada BCF STATUS,RP0 ;Banco 0 MOVLW 0x01 MOVWF T1CON ;Configura Timer1 modo temporizador, preesc 1/1 CLRF TMR1H ;Inicializa en cero el timer 1 CLRF TMR1L ; CLRF CCP1CON ;limpia latch de CCP1 BSF CCP1CON,CCP1M2 ;Habilita modulo CCP1 para modo de captura BSF CCP1CON,CCP1M0 ;en transicin de subida BCF PIR1,CCP1IF ;limpia bandera de interrupcion. ;checa bandera ;si no se ha activado espera. Cuenta del periodo ;si ya se activ, la limpia ;limpia la cuenta del timer 1 ;copia periodo capturado ;y lo enva por el puerto serie ;enva separador

checa BTFSS PIR1,CCP1IF GOTO checa BCF PIR1,CCP1IF CLRF TMR1L CLRF TMR1H MOVF CCPR1H,W CALL envbyte MOVF CCPR1L,W CALL envbyte MOVLW 0x0D CALL envia MOVLW 0x0A CALL envia GOTO checa

;repite

;*************************************************************** ; Subrutina que enva el byte en W por el puerto serie, separado ; en los cdigos ASCII de sus dos nibbles hexadecimales ;*************************************************************** envbyte: MOVWF msnib ;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

46

CALL asc CALL envia RETURN asc ADDWF PCL,1

;obtiene cdigo ASCII equivalente ;lo enva por el puerto serie

;Calcula el cdigo a retornar ;Saltando W instrucciones adelante DT "0123456789ABCDEF"

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

En el ejemplo anterior, el valor del dato (N) de 16 bits desplegado se puede convertir a segundos (T) de acuerdo a la relacin T = 4*N/Fosc = (2,712673611*10-7) N seg. O bien, como frecuencia: F= 1/T= 3686400 / N Hertz. Observacin. El programa debera leer sin problemas periodos entre Tmx= 17,777 mseg (Fmin = 56,25 hertz) y un Tmin=0,271seg (Fmx =3,6864 Mhz), sin embargo debido al retardo de la rutina de transmisin del dato, (en la realidad el programa no puede detectar ninguna transicin de subida durante la transmisin del dato) el programa slo puede procesar correctamente la transicin hasta una frecuencia Fmx =160Hz (Tmin = 6,25 mseg). Anlisis del cdigo
En primer lugar configuramos el registro T1CON y CCP1CON. Registro T1CON T1CON=0x01 --0 --0 T1CKPS1 0 T1CKPS0 0 T1OSCEN 0 T1SYNC 0 TMR1CS 0 TMR1ON 1 47

Bit 7 Divisor de frecuencia del preescaler a 1/1, T1CKPS1=0 T1CKPS0=0 TMR1CS=0, seleccin de la fuente de reloj a modo temporizador TMR1ON=1, habilitacin del Timer1 Registro CCP1CON: --Bit 7 --CCP1X 0 CCP1Y 0 CCP1M3 0 CCP1M2 1 CCP1M1 0

Bit 0

CCP1M0 1 Bit 0

Configurado el Mdulo 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 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

Subrutinas. Son tres, envbyte, initrans y envia:

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 14.7456 MHZ. envia, subrutina para enviar el byte guardado en W por el puerto serie.

48

Você também pode gostar