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 CCS Technical Support

need help-timer0 interrupt does not run for second time

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



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

need help-timer0 interrupt does not run for second time
PostPosted: Wed Aug 05, 2009 6:36 am     Reply with quote

Hello guys I'm writing a timer for my fan using 12F675. In this code initially I disable timer0 interrupt then at some point I enable it and execute a code part and then disable it again. Then I enable timer0 interrupt for the second time at another point. But problem is after enabling it for second time timer0 interrupt does not happen. Timer0_isr code does not run after this second time of enabling it.

I'm posting my total code here. Its pretty rough code I'm still try to fix basic stuff. I have added comments in places where timer0 interrupt enable and disable.

Can someone point me the error?
Code:

#include "C:\Documents and Settings\Aruna\My Documents\fan project\adding timer\main.h"

int speed=0;
int count=0;
int k=0;
int timer0_on=0;
int timer_mode=0;
int16 timer0_count=0;
int timer_set=0;
int time_min=0;
int timer_det_mode = 0;
int timer_set_mode = 0;
int second=0;
int minute=0;
int quater_mili=0;
int x=0;
void set_timer();
void finalize_timer();

VOID chk_ir  ()
{
   IF ( ! input (PIN_A3) &&k == 0)
   {
      count++;
      delay_ms (1000);
      k = 1;
     
      IF (speed != 5 &&count <= 5)
      {
         output_low (PIN_A1);
         output_high (PIN_A5);
         delay_ms (100);
         output_low (PIN_A5);
         speed++;
      }
     
      else IF (count == 6)
      {
         speed = 0;
         
         timer_det_mode = 1;
         enable_interrupts (INT_TIMER0); //eneabling for first time;
         timer0_on = 1;
         output_high (PIN_A1);
         //delay_ms (50);
         //output_low (PIN_A5);
         //output_high (PIN_A4);
         //delay_us (100);
         //output_low (PIN_A4);
         //speed = 0;
         //speed++;
      }

      else IF (count >= 7)
      {
         count = 0;

         IF (timer_mode == 0)
         {
            output_low (PIN_A1);
            disable_interrupts (INT_TIMER0);
            output_high (PIN_A4);
            delay_us (100);
            output_low (PIN_A4);
            speed = 0;
         }

         //output_high (PIN_A5);
         //delay_ms (50);
         //output_low (PIN_A5);
      }

      k = 0;
   }
}

#INT_EXT

void  EXT_isr(VOID)
{
   chk_ir ();

   IF (speed == 0)
   {
      output_low (PIN_A0);
   }

   else IF (speed == 1)
   {
      delay_ms (8);
      output_high (PIN_A0);
      delay_us (100);
      output_low (PIN_A0);
   }

   else IF (speed == 2)
   {
      delay_ms (6);
      output_high (PIN_A0);
      delay_us (100);
      output_low (PIN_A0);
   }

   else IF (speed == 3)
   {
      delay_ms (4);
      output_high (PIN_A0);
      delay_us (10);
      output_low (PIN_A0);
   }

   else IF (speed == 4)
   {
      delay_ms (2);
      output_high (PIN_A0);
      delay_us (10);
      output_low (PIN_A0);
   }

   else IF (speed == 5)
   {
      delay_us (1500);
      output_high (PIN_A0);
      delay_us (10);
      output_low (PIN_A0);
     
      //delay_ms (500);
   }
}

#INT_TIMER1
void  TIMER1_isr(VOID)
{
   quater_mili++;

   IF (quater_mili == 4)
   {
      quater_mili = 0;
      second++;

      IF (second == 60)
      {
         second = 0;
         minute++;

         IF (minute == time_min)
         {
            output_low (PIN_A0);
            minute = 0;
            time_min = 0;
            disable_interrupts (INT_TIMER1);
         }
      }
   }
}

#INT_TIMER0
void  TIMER0_isr(VOID)
{

   IF (timer_det_mode == 1)
   {
      IF (timer0_count < 5000)
      {
         timer0_count++;
      }

      else IF (timer0_count >= 5000)
      {
         //timer mode on
         timer_mode = 1;
         
         disable_interrupts (INT_TIMER0);
         
         timer0_count = 0;
         set_timer ();
      }
   }

   IF (timer_set_mode == 1)
   {
      output_low (PIN_A1);
      //delay_ms (50);

      IF (timer0_count < 3000)
      {
         timer0_count++;
      }

      else IF (timer0_count >= 3000)
      {
         disable_interrupts (INT_TIMER0);
         timer0_count = 0;
         finalize_timer () ;
         
         //set_timer ();
      }
   }
}


void finalize_timer() // this code does not run
{
   output_high (PIN_A5);
   delay_ms (50);
   output_low (PIN_A5);
   delay_ms (50);
   output_high (PIN_A5);
   delay_ms (50);
   output_low (PIN_A5);
   delay_ms (50);
   output_high (PIN_A5);
   delay_ms (50);
   output_low (PIN_A5);
   
   output_high (PIN_A4);
   delay_us (100);
   output_low (PIN_A4);

   //timer mode on
   timer_mode = 0;
   timer_set = 1;
   timer_set_mode = 0;
   enable_interrupts (INT_TIMER1);
}

void set_timer() // this code runs
{
   disable_interrupts (INT_EXT);
   timer_det_mode = 0;
   
   output_high (PIN_A5);
   delay_ms (50);
   output_low (PIN_A5);
   delay_ms (50);
   output_high (PIN_A5);
   delay_ms (50);
   output_low (PIN_A5);
   
   output_high (PIN_A4);
   delay_us (100);
   output_low (PIN_A4);
   timer0_count=0;
   timer_set_mode = 1;

   x=1;
   enable_interrupts (INT_TIMER0);// eneabling for second time

   time_min = 0;
   
   WHILE ( ! timer_set)
   {
   
    output_high (PIN_A1);
      IF (! input (PIN_A3))//time_min should be<270----- need to add
      {
         delay_ms (500);
         output_low (PIN_A1);
         timer0_count = 0;
         time_min = time_min + 30;
         output_high (PIN_A5);
         delay_ms (100);
         output_low (PIN_A5);
      }
   }
}

void main()
{
   setup_adc_ports (NO_ANALOGS|VSS_VDD);
   setup_adc (ADC_OFF);
   setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_4);
   setup_timer_1 (T1_INTERNAL|T1_DIV_BY_4);
   setup_comparator (NC_NC);
   setup_vref (FALSE);
   
   output_low (PIN_A5);
   output_high (PIN_A4);
   delay_ms (10);
   output_low (PIN_A4);
   delay_ms (1000);
   
   enable_interrupts (INT_EXT);
   disable_interrupts (INT_TIMER1);
   disable_interrupts (INT_TIMER0);
   enable_interrupts (GLOBAL);

   // TODO: USER CODE!!
   
   WHILE (1)
   {
      chk_ir ();
   }
}
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 7:04 am     Reply with quote

Your problem most likely is to do with the fact that
set_timer is called from within your interrupt, during set_timer you have a loop which relies on a variable being changed outside the loop (from within another/same interrupt)
Code:

 WHILE ( ! timer_set)
   {
   
    output_high (PIN_A1);
      IF (! input (PIN_A3))//time_min should be<270----- need to add
      {
         delay_ms (500);
         output_low (PIN_A1);
         timer0_count = 0;
         time_min = time_min + 30;
         output_high (PIN_A5);
         delay_ms (100);
         output_low (PIN_A5);
      }
   }

timer_set will always be false as the code that sets it can't run because you are curently inside an interrupt routine, only 1 int at a time.
That is appart from the fact the the routine which changes that variable is the same interrupt routine which you are curently in!

This is a bit of a mess and needs a lot of work.
aruna1



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 7:40 am     Reply with quote

ok I got it. Anyway can you suggest an alternative method?
thanks
aruna1



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 7:45 am     Reply with quote

Wayne_ wrote:
Your problem most likely is to do with the fact that
set_timer is called from within your interrupt,



Code:
WHILE ( ! timer_set)
   {
   
    output_high (PIN_A1);
      IF (! input (PIN_A3))//time_min should be<270----- need to add
      {
         delay_ms (500);
         output_low (PIN_A1);
         timer0_count = 0;
         time_min = time_min + 30;
         output_high (PIN_A5);
         delay_ms (100);
         output_low (PIN_A5);
      }


this part is running.i add a led to see whether its running. how ever shouldent timer0 interrupt navigate execution from above code part to timer0_isr? (if interrupts are occuring) it seems there are no interrupts are generating


Last edited by aruna1 on Wed Aug 05, 2009 7:48 am; edited 1 time in total
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 7:47 am     Reply with quote

Your main loop isn't doing much!

You can probably put the
Code:

   WHILE ( ! timer_set)
   {
   
    output_high (PIN_A1);
      IF (! input (PIN_A3))//time_min should be<270----- need to add
      {
         delay_ms (500);
         output_low (PIN_A1);
         timer0_count = 0;
         time_min = time_min + 30;
         output_high (PIN_A5);
         delay_ms (100);
         output_low (PIN_A5);
      }
   }


in there

Code:

while (1)
{
   chk_ir ();
   if( ! timer_set)
   {
   
    output_high (PIN_A1);
      IF (! input (PIN_A3))//time_min should be<270----- need to add
      {
         delay_ms (500);
         output_low (PIN_A1);
         timer0_count = 0;
         time_min = time_min + 30;
         output_high (PIN_A5);
         delay_ms (100);
         output_low (PIN_A5);
      }
   }
}


you may have to remove the delays, depends on how often you need to run chk_ir.

A counter flag depending on how acurate the delays need to be.

Also not sure what you are toggling A5, A1, A4 etc. Is it infared ?
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 7:48 am     Reply with quote

Quote:
set_timer is not called inside a interrupt routine.


Code:

#INT_TIMER0

void  TIMER0_isr(VOID)
{

   IF (timer_det_mode == 1)
   {
      IF (timer0_count < 5000)
      {
         timer0_count++;
      }

      else IF (timer0_count >= 5000)
      {
         //timer mode on
         timer_mode = 1;
         
         disable_interrupts (INT_TIMER0);
         
         timer0_count = 0;
         set_timer ();      <-----------------What is this then ?
      }
   }

   IF (timer_set_mode == 1)
   {
      output_low (PIN_A1);
      //delay_ms (50);

      IF (timer0_count < 3000)
      {
         timer0_count++;
      }

      else IF (timer0_count >= 3000)
      {
         
         disable_interrupts (INT_TIMER0);
         timer0_count = 0;
         finalize_timer () ;         <---------------------AND this is where your timer_set flag gets set
         
         
         //set_timer ();
      }
   }
}
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 7:54 am     Reply with quote

You edited your post and removed that comment!

Anyway, imagine this

Code:

-->Timer0 Interrupts
   |---->Call Set_timer
        |--------Enters loop and waits for timer_set flag
             (Loop never exits because we are already processing an interrupt, another interrupt cannot trigger ESPECIALLY the same one we are curently processing, which is required to set the timer_set flag)

aruna1



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 7:59 am     Reply with quote

Wayne_ wrote:
You edited your post and removed that comment!

Ya I was having trouble understanding your first post. I have understand it incorrectly. As soon as I figred it I removed the comment Embarassed

It seems working now. Thank you very much for helping Very Happy
aruna1



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 8:00 am     Reply with quote

Wayne_ wrote:
Your main loop isn't doing much!


you may have to remove the delays, depends on how often you need to run chk_ir.

A counter flag depending on how acurate the delays need to be.

Also not sure what you are toggling A5, A1, A4 etc. Is it infared ?


delays are for debouncing A5,A4 are for 7-segment drive.A1 for a led
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 8:02 am     Reply with quote

Glad to be of help.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Aug 05, 2009 9:03 am     Reply with quote

one other item I see in your ISR's which are regularly frowned on in the world of programming:

Don't use delay's inside ISR's. (delay_ms, delay_us)... especially long ones.

Debounce switches OUTSIDE the ISR.

Set a flag inside the ISR that is monitored OUTside the ISR and then run when the flag is set.

Cheers,

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
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