Tutorial Ix

4
TUTORIAL IX OBJETIVOS Crear códigos en C de mayor complejidad. Atender interrupciones por desbordamiento del Timer1 Realizar el Noveno Proyecto: Prender y apagar led en tiempo preciso. Repasar y reafirmar los conceptos vistos hasta el momento. PROYECTO 9: Prender y apagar led en tiempo preciso. Este proyecto es básicamente el mismo que el proyecto 1 del curso 1 en el que se habilitó un led intermitente a intervalo de un segundo, intervalo de tiempo generado por rutinas preestablecidas en PICC (delay.h y delay.c) Esta vez nosotros mismos generaremos el delay usando el Timer1 y un cristal de 32768 Hz lo que nos va a garantizar precisión de reloj digital en la generación del tiempo. Veamos primero que es el Timer1 y como lo podemos configurar para el proyecto: Registros asociados a Timer1 Timer1 es un modulo temporizador/contador de 16 bits del PIC16F877A, cuenta de 0 a 65535 (0000h a FFFFh) y almacena tal valor en dos registros de lectura escritura de 8 bits: TMR1L y TMR1H parte baja y alta del registro TMR1 respectivamente. Comparando con el Timer0, que solo es de 8 bits, tenemos que este ultimo siempre está contando y el Timer1 tiene opción de activar/desactivar. Esta y otras opciones del Timer1 se pueden configurar en el registro T1CON. Veamos detalladamente cada bit de este registro. Bit0: TMR1ON (Timer1 On Bit) 1: Inicia Conteo Timer1 0: Para Conteo Timer1 Bit1: TMR1CS (Timer1 Clock Source Select) 1: Habilita Modo Contador 0: Habilita Modo Temporizador Bit2: T1SYNC (Timer1 External Clock Input Synchronization Control)

Transcript of Tutorial Ix

Page 1: Tutorial Ix

TUTORIAL IX OBJETIVOS

• Crear códigos en C de mayor complejidad.

• Atender interrupciones por desbordamiento del Timer1

• Realizar el Noveno Proyecto: Prender y apagar led en tiempo preciso.

• Repasar y reafirmar los conceptos vistos hasta el momento. PROYECTO 9: Prender y apagar led en tiempo preciso. Este proyecto es básicamente el mismo que el proyecto 1 del curso 1 en el que se habilitó un led intermitente a intervalo de un segundo, intervalo de tiempo generado por rutinas preestablecidas en PICC (delay.h y delay.c) Esta vez nosotros mismos generaremos el delay usando el Timer1 y un cristal de 32768 Hz lo que nos va a garantizar precisión de reloj digital en la generación del tiempo. Veamos primero que es el Timer1 y como lo podemos configurar para el proyecto: • Registros asociados a Timer1

Timer1 es un modulo temporizador/contador de 16 bits del PIC16F877A, cuenta de 0 a 65535 (0000h a FFFFh) y almacena tal valor en dos registros de lectura escritura de 8 bits: TMR1L y TMR1H parte baja y alta del registro TMR1 respectivamente. Comparando con el Timer0, que solo es de 8 bits, tenemos que este ultimo siempre está contando y el Timer1 tiene opción de activar/desactivar. Esta y otras opciones del Timer1 se pueden configurar en el registro T1CON. Veamos detalladamente cada bit de este registro. Bit0: TMR1ON (Timer1 On Bit) 1: Inicia Conteo Timer1 0: Para Conteo Timer1 Bit1: TMR1CS (Timer1 Clock Source Select) 1: Habilita Modo Contador 0: Habilita Modo Temporizador Bit2: T1SYNC (Timer1 External Clock Input Synchronization Control)

Page 2: Tutorial Ix

Si TMR1CS = 1 1: Habilita Modo Contador 0: Habilita Modo Temporizador Si TMR1CS = 0 No Importa Bit3: T1OSCEN (Timer1 Oscillator Enable Control) 1: Habilita Oscilador 0: Deshabilita Oscilador

Bit4-5: T1CKPS1:T1CKPS0 (Timer1 Input Clock Prescale Select bits) Selecciona Prescaler

11 Prescaler 1:8 10 Prescaler 1:4 01 Prescaler 1:2 00 Prescaler 1:1

Bit6-7: No implementados. Se leen como 0. También se puede habilitar una interrupción por desbordamiento de TMR1 (cuando pasa de FFFFh a 0000h) al poner en uno los bit 6 y 7 del INTCON y el bit 0 del PIE1. Asociada a esta interrupción está la bandera TMR1IF (bit 0 del registro PIR1) que se pone en 1 en caso de que ocurra el desbordamiento y se puede borrar por software. Cuando Timer1 trabaja en modo temporizador incrementa el conteo a una frecuencia igual a la interna de trabajo (Fosc/4) En modo Contador Timer1 puede ser además síncrono ó asíncrono. Cuando es contador síncrono el incremento del Timer1 se efectúa en cada flanco de subida de los pulsos del reloj de entrada por el pin RC0 o por el pin RC1 (dependiendo del estado del bit 3 del registro T1CON) y lo hace síncronamente en fase con el reloj interno. Asincronamente no ocurre esto (usualmente se trabaja así) teniendo en cuenta además que para escritura del TMR1 en este modo se recomienda parar el modulo escribir los registros y volverlo a activar para evitar un comportamiento errático. El TMR1 posee además un prescaler que aplica en todos los modos de operación y que permite ampliar la base de tiempo. Se configura con los bits 4 y 5 del registro T1CON. Prescaler de 1:4 por ejemplo, implica que por cada 4 pulsos TMR1 incrementa en uno, sin importar de que fuente provengan los pulsos (la fuente de los pulsos depende del modo de operación como ya se mencionó) El delay que puede generar el Timer1 en modo temporizador viene dado por la expresión:

Delay(ms) = [65536 – (TMR1H:TMR1L)]*Prescaler*(4/Fosc)*1000 (1)

Despejando de esta expresión tenemos que:

Page 3: Tutorial Ix

TMR1H:TMR1L = 65536 – _Delay(ms)*Fosc_ (2) Prescaler*1000*4

De manera similar las expresiones para Timer1 como contador:

Delay(ms) = [65536 – (TMR1H:TMR1L)]*Prescaler*(1/Fosc_externo)*1000 (3) TMR1H:TMR1L = 65536 – Delay(ms)*Fosc_externo_ (4) Prescaler*1000*4

Sea por ejemplo Delay(ms) = 1000 y Timer1 configurado como contador con un cristal de 32768 Hz conectado a los pines RC0 y RC1 (ver esquemático) y con un prescaler 1:1 aplicando la ecuación 4 es posible verificar que TMR1H:TMR1L = 32768. Para poder hacer tal asignación debemos pasar ese numero a binario de 16 bits y colocar los 8 bits de menor peso en TMR1L y los 8 de mayor peso en TMR1H, para este caso: 32768= 1000000000000000 (un uno con 15 ceros) y por tanto los dos registros que unidos son TMR1 quedan: TMR1H = 0b10000000; TMR1L = 0b00000000; Una forma alterna e igual de valida es hacer la conversión a hexadecimal y hacer la asignación, en cuyo caso nuestro ejemplo quedaría: TMR1H = 80h; TMR1L = 00h; El proyecto del presente tutorial busca prender y apagar un led conectado a RB7 cada 16 segundos usando el cristal externo, siguiendo un procedimiento similar al del ejemplo y configurando los respectivos bits para que el Timer1 trabaje como Contador asíncrono. Para el proyecto en MPLAB y PICC hacemos exactamente los mismos pasos para crear un proyecto en C visto en los primeros proyectos, copiamos el siguiente código, compilamos y hacemos el respectivo montaje: #include <PIC.H> void interrupt inter(void) //Servicio a Interrupciones { if (RB7==1) //Si el led está prendido RB7=0; //Entonces apáguelo else RB7=1; //Si el led está apagado entonces préndalo TMR1IF = 0; //En cualquier caso borre bandera de la interrupción }

Page 4: Tutorial Ix

void main(void) //Programa Principal { //Configuración Puertos y de Timer1 TRISB = 0b01111111; TRISC = 0b11111111; INTCON = 0b11000000; //se habilita interrupciones globales y periféricas. TMR1H = 0; //se inicia el TMR1 en 00h TMR1L = 0; T1CON = 0b00111110; //Se selecciona el prescalador en 1:8 es decir:

// (T1CKPS1=1/T1CKPS0=1) //Se activa oscilador (T1OSCEN=1)

//Se desactiva la sincronización (T1SYNC=1) //Se selecciona como temporizador (TMR1CS=1) TMR1IE = 1; //Habilita int. por desbordamiento de TMR1 TMR1IF = 0; //Se desactiva la bandera RB7 = 1; //Inicialmente prenda el led TMR1ON = 1; //Inicie el conteo del TMR1 for (;;); //Ciclo infinito en el que el PIC no efectúa ninguna operación { } }

DIAGRAMA DE CONEXIONES