4 votos

Cálculo de momento de Timer0 C18 usando MCC18

Yo soy la programación de un PIC18F4520 y he configurado para utilizar un 32Mhz reloj interno.

Necesito un contador para marcar cada segundo, así que estoy usando TMR0 para este propósito.

El uso de TMR0, me he puesto el siguiente:

  • Prescaler de 1:256
  • 16 Bits modo de
  • Alto nivel de interrupción en TMR0 de desbordamiento.

Para establecer el temporizador de cuenta cada 1 segundo, he calculado de la siguiente manera:

TMR0 = (Required time)/(4 * Timer clock * prescale value)
     = 1 / (4  * (1/32000000) * 256)
     = 31250

Así, TMR0 = 0xFFFF - 31250.

Es esto correcto? Si no, ¿qué me estoy perdiendo? El código es el siguiente:

#pragma code
void main(void)
{
    //Set clock frequency
    OSCCON |= 0x70;             //8 Mhz clock, primary clock
    OSCTUNEbits.PLLEN = 1;          //4x Multiplier, thus we have 32 Mhz clock
    while (!OSCCONbits.IOFS);       //Wait until INTOSC is stable.

    //Enable TRISA as analog input (For ADC)
    TRISA = 0x2F;

    //PIN Outputs
    TRISB = 0;              //Make PORTD as output
    //Reset PORTB
    PORTB = 0;

    //Set ADC
    OpenADC(ADC_FOSC_32 &           //Fosc/32
         ADC_RIGHT_JUST &
         ADC_4_TAD,             //4xTAD
         ADC_CH0 &
         ADC_REF_VDD_VSS &
         ADC_INT_OFF, ADC_5ANA);        //ADC CH0-CH4 Initialized

    //Set Timer0
    OpenTimer0( TIMER_INT_ON &
                T0_16BIT &
                T0_SOURCE_INT &
                T0_PS_1_256);

    //Write Timer
    WriteTimer0(CLOCK_TICK);

    INTCON2bits.TMR0IP = 1;         //TMR0 has high overflow interrupt priority
    RCONbits.IPEN = 1;                  //enable priority levels
    INTCONbits.GIEH = 1;            //enable high interrupts

    //Begin
    while (TRUE)
    {

    }

    CloseADC();             //Closing ADC
    CloseTimer0();
}

En mi alto nivel de vector de interrupción, he hecho esto:

#pragma code 
#pragma interrupt high_priority_interrupt 
void high_priority_interrupt()
{
    if (INTCONbits.TMR0IF)                  //TIMER0 overflowed
    {
        //Stuff
        second += 1;
        if (second == 60)
        {
            minute += 1;
            second = 0;
        }

        if (minute == 60)
        {
            measure_and_switch();
            WriteTimer0(CLOCK_TICK);
            minute = 0;
        }

        INTCONbits.TMR0IF = 0;              //Clear TIMER0 overflow bit.
    }
}

Así que, básicamente, cada 2 minutos, quiero que el método measure_and_switch() a ser ejecutado. Debo seguir con la WriteTimer0()?

Por cierto,: CLOCK_TICK es TMR0 (cálculo de la anterior).

Gracias

4voto

dko Puntos 386

La respuesta es sencilla. Cuando el bit de desbordamiento se produce y se produce la interrupción, tenemos que escribir primero el contador y restablecer la bandera.

Esta solución funciona:

Espero que esto ayude a alguien. :-)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X