CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Enable Timer1 interrupt in another ISR?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pe1icq



Joined: 29 Aug 2005
Posts: 12

View user's profile Send private message

Enable Timer1 interrupt in another ISR?
PostPosted: Fri Sep 29, 2006 10:41 am     Reply with quote

Hi,

Can I setup and enable a Timer1 interrupt in another ISR?
What I'm trying to accomplish is starting Timer1 in the ISR that handles the PortA change interrupts.
I've tried several things but I can't get it to work.
This is what I have:

Code:

#define INTS_PER_MINUTE 114        // (4000000/(4*8*65536)) * 60

int8 minutes;      // A running minutes counter
int8 int_count;    // Number of interrupts left before a minute has elapsed


#PRIORITY TIMER1,RA

#INT_TIMER1                        // This function is called every time
void clock_isr()                   // timer 1 overflows (65535->0), which is
{                                  // approximately 1.9 times per second for
                                   // this program.
    output_high(pin_a3);        // Green LED

    if(--int_count==0) {
        ++minutes;
        int_count = INTS_PER_MINUTE;
    }

    if (minutes==2) {
        output_high(pin_a5);
        // delay_ms(1000);
        // output_low(pin_a5);
    }
}

#INT_RA
void porta_change_isr()
{
        delay_us(250);
        if (!input(PIN_A4)) {
                disable_interrupts(INT_TIMER1);
                output_low(pin_a5);             // Red LED
        }
        if (input(PIN_A4)) {
                int_count = INTS_PER_MINUTE;
                minutes = 0;
                setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
                set_timer1(0);
                enable_interrupts(INT_TIMER1);
                output_high(pin_a5);            // Red LED
        }
        #use fast_io(a)
        input_a();      // dummy read
}

I can get in an out of the RA ISR. The LED on pin_a5 goes on and off. However Timer1 does not seem to be running, and I never get into the Timer1 ISR (I.e. the debug LED on pin_a3 never goes on)

What am I doing wrong?

BR. //Arno
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 11:25 am     Reply with quote

Stupid question, but did you configure timer 1 to run? ie.

Code:
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
pe1icq



Joined: 29 Aug 2005
Posts: 12

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 12:28 pm     Reply with quote

Yes I did. It is in the #INT_RA ISR.
I also tried putting it in main() but that did not make a difference.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 1:20 pm     Reply with quote

What PIC are you using, and what's your compiler version ?
pe1icq



Joined: 29 Aug 2005
Posts: 12

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 1:51 pm     Reply with quote

PIC16F684 and PCM compiler version 3.229 (Linux)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 2:37 pm     Reply with quote

Can you post a main() function, with all of your setup code for the
timer, and the port i/o pins, comparators, etc., ?

Please show the #fuses, #use, and applicable #define statements.

In other words, I want to drop the code into MPLAB and have it compile
with no errors. Then I can look at it.
pe1icq



Joined: 29 Aug 2005
Posts: 12

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 2:39 pm     Reply with quote

Well... it would help if I would select a port for the debug LED that actually can be used as an output. RA3 isn't one of those. Embarassed
I swapped RA3 and RA4 and now everything is working fine.

I still have one question. Do I explicitely need to clear the interrupt flags, or does the compiler take care of that for me?
I now have some clear_interrupt() statements in the ISR as shown below. Are those really needed?
Code:

#INT_RA
void porta_change_isr()
{
        delay_ms(200);
        if (!input(PIN_A3)) {
                disable_interrupts(INT_TIMER1);
                output_low(pin_a5);             // Red LED
        }
        if (input(PIN_A3)) {
                int_count = INTS_PER_MINUTE;
                minutes = 0;
                setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
                set_timer1(0);
                clear_interrupt(INT_TIMER1);
                enable_interrupts(INT_TIMER1);
                output_high(pin_a5);            // Red LED
        }
        clear_interrupt(INT_RA);
}
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 2:41 pm     Reply with quote

Clearing the interrupt is absolutely required. The compiler doesn't take care of that for you. If a timer is enabled, it will set its overflow flag when it overflows regardless of whether its interrupt is enabled.

Whoops - have to clarify. If you enable the timer interrupt, you must clear any outstanding timer interrupts. As PCM has said, no need to clear the other one - the compiler does that automatically.


Last edited by newguy on Fri Sep 29, 2006 3:19 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 2:55 pm     Reply with quote

You don't need to clear the RA interrupt flag at the end of the isr.
The compiler automatically puts in a line of ASM code to do that for you.
See the lines shown in bold below.
Quote:
.................... }
.................... clear_interrupt(INT_RA);
0088: BCF 0B.0.................... }
....................
....................
0089: BCF 0B.0
008A: BCF 0A.3
008B: GOTO 02B
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 5:09 pm     Reply with quote

You can turn on/off a timer from anywhere in your code, including an ISR. Simply set/clear the bit that enables the timer.

Ronald
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Sat Sep 30, 2006 5:12 pm     Reply with quote

pe1icq wrote:
Do I explicitely need to clear the interrupt flags, or does the compiler take care of that for me?
Code:


                set_timer1(0);
                clear_interrupt(INT_TIMER1);
                enable_interrupts(INT_TIMER1);


That first line of code will set the counter to zero
the second line will clear the interupt flag that may have already been set by an overflow of timer 1 counter.
The third line will enable interupt if the timer interupt flag is set.

If you dont clear the interupt flag before enabeling the interupt it might jump to the timer 1 interupt routine as soon as it leaves the RA interupt.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group