0
\$\begingroup\$

I am working with a PIC24FJ1024.

I want to test Timer 2/3 (32 bit timer), by writing a C code, where I toggle a pin (PORTAbits.RA7) every second.

That is part of the code:

while(!IFS0bits.T2IF);
LATAbits.LATA7 = ~LATAbits.LATA7;
IFS0bits.T2IF = 0;  

When I compile and download it onto my Development Tool (Explorer 16/32), I don't see my Pin (which is connected to an LED) Toggle.

I debug program, and it turns out that IFS0bits.T2IF doesn't get set, the program just sits on while(!IFS0bits.T2IF)

Can someone explain to me why this happens?

Thank you in advance.

EDIT: The Code

#include <xc.h>

#pragma config FWDTEN = OFF
#pragma config FNOSC = FRC //8MHz 
#pragma config ICS = PGD2

void Timer23_Init (void)
{
    /*
     Initialize T2 & 3
     from FRC
     * 1 second
     * on and off

     */

    T2CONbits.T32 = 1;//32 bit timer

    T2CONbits.TSIDL = 0;//continues through Idle Mode
    T2CONbits.TGATE = 0;//no TGATE Operationss
    T2CONbits.TCS = 0;//internal CLK SRC
    T2CONbits.TECS = 0x00;

    T2CONbits.TCKPS = 3;//1:256
    /*
      PRESCALAR = 256
     * t = 1 sec = 1000 ms = 1,000,000 us
     * Fosc = 8MHz Fosc/2 = 4MHz Tcy = 0.25 us
     * 
     * t = N*PRE*Tcy
     * N = t/(PRE*Tcy) = 1,000,000/(256*0.25) = 15,625
     * PR2 = 15625 (0x3D09)    
     */

    TMR2 = 0x00000000;
    PR2 = 15625;   

    TRISAbits.TRISA7 = 0;//output
    ANSAbits.ANSA7 = 0;//Digital
    LATAbits.LATA7 = 0;

    T2CONbits.TON = 1;
}

int main (void)
{   


    Timer23_Init ();

    while(1)
    {
        IFS0bits.T2IF = 0;

        while(!IFS0bits.T2IF);
        LATAbits.LATA7 = ~LATAbits.LATA7;
        IFS0bits.T2IF = 0;  
    }

    return 0;
}
\$\endgroup\$
8
  • \$\begingroup\$ Can you show your code please where you setup the timer. \$\endgroup\$
    – R.Joshi
    Jul 10, 2017 at 9:44
  • \$\begingroup\$ Sure, I just added the code right now \$\endgroup\$ Jul 10, 2017 at 9:54
  • \$\begingroup\$ Have you enabled the timer interrupt. The microchip processor i recently been working with has something like _T2IF = 0; <- this is a macro for resetting interrupt flag initially. _T2IE = 1; -< this is a macro for interrupt enable. \$\endgroup\$
    – R.Joshi
    Jul 10, 2017 at 11:39
  • \$\begingroup\$ T1CON = 0x00; //Stops the Timer1 and reset control reg. TMR1 = 0x00; //Clear contents of the timer register PR1 = 0x8CFF; //Load the Period register with the value 0x8CFF IPC0bits.T1IP = 0x01; //Setup Timer1 interrupt for desired priority level // (this example assigns level 1 priority) IFS0bits.T1IF = 0; //Clear the Timer1 interrupt status flag IEC0bits.T1IE = 1; //Enable Timer1 interrupts T1CON = 0x8012; //Start Timer1 with prescaler settings at 1:8 \$\endgroup\$
    – R.Joshi
    Jul 10, 2017 at 11:45
  • \$\begingroup\$ Since you are polling the interrupt flag in software in your case you should be ok without enabling the interrupt. \$\endgroup\$ Jul 10, 2017 at 11:55

2 Answers 2

1
\$\begingroup\$

Can someone explain to me why this happens?

The flag is almost surely firing and your led pin flipping. Except that the pin is not in GPIO mode.

\$\endgroup\$
1
  • \$\begingroup\$ Are you sure? Because I set the mode of the pin as output TRISAbits.TRISA7 = 0, I disabled the Analogue Pin feature ANSAbits.ANSA7 = 0, when I debug the program, and the debugger was stuck on while(!IFS0bits.T2IF), I went to the SFR window, and changed the value of the IFS0 register to set T2IF , and suddenly the debugger could go to the next line, and toggle the Pin. \$\endgroup\$ Jul 10, 2017 at 11:46
0
\$\begingroup\$

Even though Timer2 and Timer3 work together in hardware as a 32-bit timer, I would load them as two 16-bit registers. The compiler is unlikely to know that you are treating them as a pair. I would do the same for PR2 and PR3. Also, I noticed in one similar datasheet (not the exact part number) that the interrupt for the higher timer (T3IF not T2IF) is the interrupt that will be affected, not the lower T2IF when they are concatenated.

\$\endgroup\$
5
  • \$\begingroup\$ Also, in the code i do not see anywhere where the timer interrupt is enabled. \$\endgroup\$
    – R.Joshi
    Jul 10, 2017 at 11:47
  • \$\begingroup\$ I am not doing an Interrupt Service Routine at the moment, this code is just inside a while loop, that waits for the delay to finish and then toggles the pin. I will try to Load PR2, and PR3 seperately, and change !IFS0bits.T2IF to !IFS0bits.T3IF \$\endgroup\$ Jul 10, 2017 at 12:02
  • \$\begingroup\$ I changed the code, instead of having PR2 = 0x3D09 I changed it to PR2 = 0x09 and PR3 = 0x3D, and instead of while(!IFS0bits.T2IF) changed it to while((IFS0bits.T2IF ==0) || (IFS0bits.T3IF == 0)), I still get the same problem. I thought maybe the problem is that I didn't enable T2 or T3 interrupts, but if that is the case, how come the same example with Timer 1 worked, without adding an interrupt \$\endgroup\$ Jul 11, 2017 at 6:19
  • \$\begingroup\$ Change your logical OR '||' to AND '&&'. Your 'while()' condition waits for both interrupt flags to assert, but I don't think both are supposed to assert. From the datasheet "Timer2 clock and gate inputs are utilized for the 32-bit timer modules, but an interrupt is generated with the Timer3 interrupt flags." \$\endgroup\$ Jul 11, 2017 at 10:54
  • \$\begingroup\$ I noticed in your response that you split a number which is small enough to fit entirely in PR2 (it is 16-bits wide) into two 8-bit values. Just put 0x3d09 (or 15760 decimal) into PR2, then clear PR3 (set it to 0). Also clear both Timer2 and Timer3 16-bit registers. Here is the microchip application notes for Timer2/3 : ww1.microchip.com/downloads/en/DeviceDoc/39704a.pdf \$\endgroup\$ Jul 11, 2017 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.