Temporizador TIMER1 con el PIC18F4550

publicado en: Sin Categoria | 0

temporizador-timer1-con-el-pic18f4550-1

DESCRIPCIÓN

El módulo TIMER1 puede funcionar como temporizador o contador de 16 bits que se almacena en dos registros TMR1H y TMR1L, al igual que el timer0, este TIMER1 presenta muchas características adicionales que se muestran a continuación.

  • Registro Contador de 16 Bits TMR1H y TMR1L
  • Ambos registros de Lectura/Escritura.
  • Fuente de Reloj Interno o Externo (programable por software).
  • Prescaler de 3 bits.
  • Funcionamiento síncrono o asíncrono.
  • Habilita la salida del modo reposo.
  • Interrupción por desbordamiento.

En las siguientes imágenes se detallan los registros involucrados al TIMER1

temporizador-timer1-con-el-pic18f4550-2temporizador-timer1-con-el-pic18f4550-3

El TIMER1 puede funcionar en uno de estos 3 modos

  1. TEMPORIZADOR: Este modo se determina escribiendo un “0” lógico en el bit TMR1CS del registro T1CON, esto permitirá que los incrementos del registro TMR1 sea en cada ciclo de instrucción interna (Fosc/4).
  1. CONTADOR ASÍNCRONO: Este modo se determina escribiendo un “1” lógico en los bits TMR1CS y T1SYNC del registro T1CON, esto permitirá que los incrementos del registro TMR1 sea en cada flanco de subida de la entrada de reloj externo por el pin RC0/T13CKI de forma asíncrona.
  1. CONTADOR SÍNCRONO: Este modo se determina escribiendo un “1” lógico en el bit TMR1CS y un “0” lógico en el bit T1SYNC, ambos en el registro T1CON, esto permitirá que los incrementos del registro TMR1 sea en cada flanco de subida de la entrada de reloj externo por el pin RC0/T13CKI y de forma síncrona. Cabe resaltar que para que se sincronice el reloj externo con el interno es necesario 2 ciclos de reloj Interno (Fosc/4).

La Interrupción por desbordamiento es para los 3 modos, esto ocurre cuando el registro TMR1 que es el encargado de llevar la cuenta, llega a su máximo valor (0xFFFF) y automáticamente se desborda a (0x0000), en ese preciso instante el Flag de estado TMR1IF se pone a “1” y si está habilitado la Interrupción a través del bit TMR1IE provocará una Interrupción por Desbordamiento.

A continuación se explicarán los PASOS para configurar el TIMER1

  1. Deshabilitar la Interrupción GLOBAL (para evitar Interrupciones falsas).
  2. Configurar la Fuente de reloj para el TIMER1 a través del bit
  3. Configurar el Prescaler a través de los bits T1CKPS1:T1CKPS0.
  4. Seleccionar el modo Síncrono o Asíncrono (solo en modo Contador).
  5. Poner en Marcha el TIMER1 escribiendo en el bit TMR1ON.
  6. Escribir en los registros TMR1H:TMR1L para configurar el Tiempo de Interrupción.
  7. Habilitar la Interrupción por Desbordamiento escribiendo el bit TMR1IE.
  8. Habilitar la Interrupción GLOBAL (GIE y PEIE).

Para poder calcular el PERIODO de Interrupción por Desbordamiento del TIMER0, es necesario las siguientes Fórmulas

temporizador-timer1-con-el-pic18f4550-4

EJEMPLO N°1 – TIMER1 EN MODO TEMPORIZADOR DE 16 BITS

En este ejemplo se muestra como controlar 4 display 7 segmentos a través de la técnica de multiplexación. Para ello utilizaremos el IC 74HC4511 que es un decodificador BCD ideal para mostrar datos en el display; tambien utilizaremos el IC 74HC138 que es un decodificador de 3 a 8 lines, esto es para poder controlar cada display. Con estos dos IC realizaremos un reloj digital que muestre los minutos y segundos, además tendrá 2 botones para iniciar y parar.

temporizador-timer1-con-el-pic18f4550-005

A través de los pines RD[0:3] controlaremos el IC 74HCT4511 el cual escribirá el valor deseado en el display 7 segmentos, con los pines RD[4:6] controlaremos el IC 74HCT138 el cual habilitara cada uno de los 4 display cada 10ms (este tiempo es para multiplexar los 4 display y poder visualizarlos al mismo tiempo). Utilizaremos el timer1 en modo temporizador de 16 bits para generar los 10ms deseados. Además se tendrá un boton para start/pause y otro de stop.

10ms = (4÷FOSC) × (PRESCALER) × (65535 – X)

10000us = (4÷8Mhz) × (2) × (65535 – X)

X = 55535 = 0xD8EF –> este valor escribiremos en el registro TMR1H y TMR1L

Código principal MAIN

/*
 * Timer1 modo temporizador de 16bits
 */
#define _XTAL_FREQ  8000000L
#include    
#include    "fuses.h"

unsigned char flag_run = 0;
unsigned char counter_digito = 0;
unsigned int counter_segundos = 0;
unsigned char counter_20ms = 0;

int main(void) {
    INTCONbits.GIE = 0; //Deshabilita la interrupción global
    T1CONbits.RD16 = 1; //Timer1 en modo 16bits
    T1CONbits.TMR1CS = 0; //Timer1 reloj interno = Fosc÷4
    T1CONbits.T1CKPS = 0b01; //Timer1 prescaler = 2
    TMR1H = 0xD8; //Registro TMR1 =  55535
    TMR1L = 0xEF;
    T1CONbits.TMR1ON = 1; //Timer1 ON
    PIR1bits.TMR1IF = 0; //Borra flag de TIMER1
    PIE1bits.TMR1IE = 1; //Habilita interrupción TIMER1
    INTCONbits.PEIE = 1; //Habilitara interrupción periféricas
    INTCONbits.GIE = 1; //Habilita interrupción global
    TRISD = 0; //PORTD como salida digital
    TRISAbits.RA0 = 1;
    TRISAbits.RA1 = 1;
    ADCON1 = 0x0F;
    CMCON = 0x07;
    while (1) {
        if (!PORTAbits.RA0) {
            __delay_ms(50);
            flag_run = !flag_run;
            while (!PORTAbits.RA0);
            __delay_ms(50);
        }
        if (!PORTAbits.RA1) {
            __delay_ms(50);
            counter_segundos = 0;
            flag_run = 0;
        }
    }
    return 1;
}

void interrupt ISR_TIMER_1(void) {
    if (PIE1bits.TMR1IE && PIR1bits.TMR1IF) {
        TMR1H = 0xD8;
        TMR1L = 0xEF;

        if (++counter_20ms == 100 && flag_run) {
            counter_20ms = 0;
            if (++counter_segundos == 3600) {
                counter_segundos = 0;
            }
        }

        switch (counter_digito) {
            case 0:
                LATD = (counter_digito << 4) + (counter_segundos / 60) / 10;
                counter_digito = 1;
                break;
            case 1:
                LATD = (counter_digito << 4) + (counter_segundos / 60) % 10;
                counter_digito = 2;
                break;
            case 2:
                LATD = (counter_digito << 4) + (counter_segundos % 60) / 10;
                counter_digito = 3;
                break;
            case 3:
                LATD = (counter_digito << 4) + (counter_segundos % 60) % 10;
                counter_digito = 0;
                break;
        }

        PIR1bits.TMR1IF = 0;
    }
}

Código FUSES

#ifndef     _H_FUSES_H_

#define     _H_FUSES_H_

// CONFIG1L
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

// CONFIG1H
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator (HS))
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = ON        // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOR = OFF        // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF      // MCLR Pin Enable bit (RE3 input pin enabled; MCLR pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config ICPRT = OFF      // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)

#endif

Deja una respuesta