TMR0, TMR2 not working.

swapan

Full Member level 4
Joined
Feb 20, 2009
Messages
204
Helped
27
Reputation
54
Reaction score
24
Trophy points
1,298
Location
Kolkata
Activity points
2,838
Hi guys,

While developing a simple code of blinking LED with PIC16F722A it is seen that TMR2 is not working. I have observed the code with Oshonsoft PIC simulator where TMR2 does not increase whereas program counter advances as usual. Interestingly, it is also seen that TMR0 is also not increases. Please see the code and suggest where is the bug. Incidentally, it is to state that configuration bit MCLR is disabled. The same code when developed with PIC16F72, works properly.

sbit LED at RB2_Bit;

unsigned char state;

void interrupt() {
if (TMR2IF_Bit == 1) {
if (state == 1) {
LED = 1;
state = 2;
TMR2IF_Bit = 0;
}

else {
LED = 0;
state = 1;
TMR2IF_Bit = 0;
}
}


void main() {

TRISA = 0x2F;
TRISB = 0x21;
TRISC = 0x2;
OPTION_REG =0x80;
ANSELB= 0x21;
INTCON = 0xC0;
T2CON = 0x5A;
TMR2ON_bit = 1;
TMR2IE_bit = 1;
PR2 = 128;
LED = 1;
state = 2;
while (1);

}
 
Last edited:

Hi,

Please use the [ C O D E ] button ... when posting code.

Please add comments to your code, so we can see what you want to achieve.

I recommend to use some according application notes, code examples, libraries, descriptions, tutorial .. to avoid re-inventing the wheel and to avoid mistakes others already made.
--> If you do so: provide a link to this source of information.

--> in either case: provide a link to the datasheet.


Klaus
 

C:
// Define LED pin
sbit LED at RB2_Bit;

// State variable
unsigned char state;

// Interrupt Service Routine
void interrupt() {
    if (TMR2IF_Bit == 1) { // Check if Timer2 interrupt occurred
        if (state == 1) {
            LED = 1;      // Turn on the LED
            state = 2;    // Update state
        } else {
            LED = 0;      // Turn off the LED
            state = 1;    // Update state
        }
        TMR2IF_Bit = 0;   // Clear Timer2 interrupt flag
    }
}

// Main function
void main() {
    // Configure I/O
    TRISA = 0x2F;         // Set PORTA directions
    TRISB = 0x21;         // Set PORTB directions
    TRISC = 0x02;         // Set PORTC directions
    ANSELB = 0x00;        // Configure PORTB pins as digital

    // Timer2 configuration
    PR2 = 128;            // Set Timer2 period register
    T2CON = 0x5A;         // Prescaler 1:16, Postscaler 1:10, Timer2 ON
    TMR2ON_bit = 1;       // Enable Timer2
    TMR2IE_bit = 1;       // Enable Timer2 interrupt

    // Interrupt configuration
    INTCON = 0xC0;        // Enable global and peripheral interrupts

    // Initial state
    LED = 1;              // Turn on the LED initially
    state = 2;            // Set initial state

    // Infinite loop
    while (1) {
        // Main loop content can go here if needed
    }
}

Key Changes and Explanations:​

  1. Interrupt Service Routine:
    • The ISR toggles the LED based on the state variable and clears the TMR2IF_Bit.
  2. Digital Pin Configuration:
    • ANSELB = 0x00; ensures all PORTB pins are set as digital. This avoids conflicts caused by default analog settings.
  3. Timer2 Configuration:
    • PR2 = 128; defines the period for Timer2.
    • T2CON = 0x5A; sets up the prescaler, postscaler, and turns on Timer2.
  4. Interrupt Setup:
    • INTCON = 0xC0; enables global and peripheral interrupts.
    • TMR2IE_bit = 1; specifically enables Timer2 interrupts.
  5. Infinite Loop:
    • The while(1) loop keeps the program running indefinitely. Additional code can be added inside this loop if needed for other functionalities.

Notes:​

  • Configuration Bits: Verify that the configuration bits are correctly set in your IDE to match the intended hardware settings, especially for the oscillator and MCLR. If MCLR is disabled, ensure it is appropriately handled in the hardware circuit.
 

Hi,

I can´t help with the compiler / simulator error.

*****

ISR:
* you check the TMRInterruptFlag. So far so good. You probably do this to distinguish if any other interrrupt occured.
Now let´s imagine INDEED any other interrupt occured. What happens then? And what happens when you don´t clear this (other) interrupt flag?
I have no experience with PICs, so I don´t know.
(maybe it restarts the ISR immedately after leaving, maybe it stops ISR form being called) So, to be on the safe side, I´d probably clear ALL interrupt flags when leaving the ISR.

Or even better: I´d save the flags into a register ... and clear all flags by_using_this_register at the very beginning of the ISR.
So you still have the flags in your register ... while you don´t lose an interrupt that occurs while you are processing the ISR.
This is not very critical when your ISR only processes one interrupt source .. but for the future, for expansions, for other applications...

Klaus
 

No interrupt is active other than TMR2 interrupt. The code has been run with simulator which shows neither TMR0 nor TMR2 increments whereas PC increments as usual. The same code with PIC16F72 device on same hardware works fine.
 

Just now I have practically tested the code. It works properly. I think there is problem in simulator.
 

Cookies are required to use this site. You must accept them to continue using the site. Learn more…