4 votos

interrumpir el uso de Timer0 en PIC18f

Estoy buscando un poco de ayuda y consejos en mi código.

Estoy usando el C18 en el entorno MPLab, PIC18f4520 con Fosc @ 4 mhz, y usnig timer0 en 16 bits modo de contar el desbordamiento, establezca el bit de desbordamiento y el indicador de interrupción, a continuación, saltar a la ISR y el incremento de una variable 'contar'. Este es arrojado a un puerto con Led conectado para que yo pueda obtener visualy la confirmación de que el programa de trabajo.

Sin embargo, la emitida contar es siempre " 1 " (es decir, 0x01) y creo que el ISR es sólo sucede una vez, en todo caso.

Cualquier ayuda que usted puede ofrecer sería más apreciado.

Aquí está mi código:

void main (void)        /*                                                                                      */
{                   
TRISA = 0;          /*                                                                                      */
TRISC = 0;          /*                                                                                      */
TRISB = 0;
TRISD = 0x00;
RTOS();
}
void low_interrupt (void)
    {
    _asm GOTO timer_isr _endasm
    }
    #pragma code
    #pragma interruptlow timer_isr 

void timer_isr (void)
    {
    INTCONbits.TMR0IF = 0;
    count = count++;
    LATD = count;
    RTOS();
    }
void RTOS (void)
    {
    T0CONbits.T08BIT = 0;   // 16-bit timer
    T0CONbits.T0CS = 0;     // increment on instruction cycle input
    T0CONbits.T0SE = 0;     // increment on low--> high transition of clock
    T0CONbits.PSA = 1;      // T0 prescaler not assigned i.e. 1:1 prescaler.
    RCONbits.IPEN       = 1;    //Enable Interrupt Priorities
    INTCONbits.GIEL     = 1;    //Enable Low Priority Interrupt
    INTCONbits.GIE      = 1;    //Enable Global Interrupts            
    INTCONbits.TMR0IE   = 1;    //Enable Timer0 Interrupt
    INTCON2bits.TMR0IP  = 0;    //TMR0 set to Low Priority Interrupt
    INTCONbits.TMR0IF = 0;  // T0 int flag bit cleared before starting
    T0CONbits.TMR0ON = 1;   // timer0 START
    while (1);
    }

Gracias de antemano por cualquier orientación que usted puede ofrecer.

4voto

tillz Puntos 126

Usted está llamando RTOS() en su interrupción y el RTOS() la función tiene "while (1);" en él (bucle infinito?)

No estoy seguro de por qué se iba a restablecer la completa interrupción se registra dentro de su interrupción.

Tener un bucle infinito en su interrupción causa más probable de su programa funcione correctamente.

También, compruebe el comentario de Roger Rowland: "¿Dónde está count definido? Ha marcado volatile? – Roger Rowland 15 minutos atrás". Este es un muy común error y podría ser también el punto aquí.

2voto

Brian J Hoskins Puntos 168

Yo no estoy familiarizado con C18, pero tengo que hacer uso de su sucesor XC8.

Con respecto a su ISR, hace el compilador C18 saber para ejecutar vacío low_interrupt (void) cuando una baja prioridad de interrupción se genera? He visto funciones designadas por las interrupciones con algunos compiladores pero XC8 funciona de la siguiente manera:

// HP int declared with 'high_priority' identifier, name function as you see fit
interrupt high_priority void isr_high(void)

// LP int declared with 'low_priority' identifier, name function as you see fit
interrupt low_priority void isr_low(void)

Si C18 hace uso de la función asignada a los nombres de lugar, asegúrese de que ha obtenido de ellas la correcta.

En segundo lugar, he aquí cómo me hubiera manejado el temporizador de desbordamiento:

interrupt high_priority void isr_high(void)
{  
    // TIMER0 Overflow
    if (INTCONbits.TMR0IF)
    {
        LATEbits.LE0 ^= 1;               // Toggle RE0
        INTCONbits.TMR0IF = 0;           // Clear the interrupt flag
    }
}

Espero que esto ayude.

0voto

Karin Puntos 6

Gracias por toda la ayuda.

Con un poco de trabajo en el MPLabSim he encontrado mi error y el código corregido a continuación funciona correctamente, al menos en el MPLabSim:

EDIT: ahora también funciona en el hardware real!!!!

 void main (void)       /*                                                                                      */
    {                   
    TRISA = 0;          /*                                                                                      */
    TRISC = 0;          /*                                                                                      */
    TRISB = 0;
    TRISD = 0x00;
    RTOS();
    }
void low_interrupt ()
    {
    _asm GOTO timer_isr _endasm
    }
    #pragma code
    #pragma interrupt low_interrupt //save =PROD
void timer_isr ()
    {
    if(INTCONbits.TMR0IF==1)
    {
    count++;
    INTCONbits.TMR0IF = 0;
    }
    }
void RTOS ()
    {
    T0CONbits.T08BIT = 0;   // 16-bit timer
    T0CONbits.T0CS = 0;     // increment on instruction cycle input
    T0CONbits.T0SE = 0;     // increment on low--> high transition of clock
    T0CONbits.PSA = 1;      // T0 prescaler not assigned i.e. 1:1 prescaler.
    RCONbits.IPEN       = 1;    //Enable Interrupt Priorities
    INTCONbits.GIEL     = 1;    //Enable Low Priority Interrupt
    INTCONbits.GIEH     = 0;    // disable high priority interrupts
    INTCONbits.GIE      = 1;    //Enable Global Interrupts            
    INTCONbits.TMR0IE   = 1;    //Enable Timer0 Interrupt
    INTCON2bits.TMR0IP  = 0;    //TMR0 set to low Priority Interrupt

    INTCONbits.TMR0IF = 0;  // T0 int flag bit cleared before starting
    T0CONbits.TMR0ON = 1;   // timer0 START
    counter(count);
    }   
void counter ()
{
LATD = count;
}   

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