Interrupts

Thread Starter

Adb

Joined Aug 24, 2012
2
Hii,
i'm working on a project using the microcontroller 'PIC16F877A' and am having problems with the interrupt...is there a limit to the number of times the interrupt routine can be called?
i'm coding in micro c and when and my problem is that when i add a 'while' loop at a point in one of the if conditions within the interrupt method,all interrupts thereafter are disabled(or appears to be because even though i give an external interrupt the PIC dosnt act accordingly),but when i comment the loop,it works perfectly...

Rich (BB code):
void interrupt() {

//First inturrupt Directive-Assigning priorities
if(no==1 || ar[0]==0){
 while(PORTC.F3==0 && full==0) {

   while(dcv==0 && PORTC.F3==0) {
       PORTD=1;
       x=1;
      if     (PORTB.F2==1){d1=1;dcv=1;}
      else if(PORTB.F3==1){d1=2;dcv=1;}
      else if(PORTB.F4==1){d1=3;dcv=1;}
      else if(PORTB.F5==1){d1=4;dcv=1;}
  }
      if(d1==4)
      y=24;
      else if(d1==3)
      y=18;
      else if(d1==2)
      y=12;
      else if(d1==1)
      y=6;
      //Delay_ms(300);
       //Delay_ms(1000);
   while(dcv==1 && PORTA.F5==0){
    if(PORTB.F1==0) {
    zi=1;
    while(zi==1 && PORTA.F5==0){
   PORTD=2;
  if     (PORTB.F2==1){d2=1;dcv=2;zi=0;}
  else if(PORTB.F3==1){d2=2;dcv=2;zi=0;}
  else if(PORTB.F4==1){d2=3;dcv=2;zi=0;}
  else if(PORTB.F5==1){d2=4;dcv=2;zi=0;}
   }

  }
       }
  if(PORTA.F5==1 && x==1){//used to avoid reading the if twise ie.if F5 is true during the second round of thw while

        x=0;

    if(nfo==0){
      if(dcv==1){
      ar[0]=d1;}
      else
      ar[0]=(((10*d1) + d2)-y);
      }


    else if(nfo==1){
      if(dcv==1)
      ar[1]=d1;
      else
      ar[1]=(((10*d1) + d2)-y);
      }
 else if(nfo==2){
 if(dcv==1)
 ar[2]=d1;
 else
 ar[2]=(((10*d1) + d2)-y);
 }
 else if(nfo==3){
 if(dcv==1)
 ar[3]=d1;
 else
 ar[3]=(((10*d1) + d2)-y);
   }
  nfo++;
  dcv=0;
  PORTD=10;
  Delay_ms(500);
  }
if(nfo==4)full=1;


  }
if(ot1==0 || ot2==0 || ot3==0 || ot4==0) {PORTD=6;
if(ar[0]>0 && PORTC.F4==0)ot1=1;
//else if(ar[0]==0)ot1=0;
if(ar[1]>0 && PORTC.F5==0)ot2=1;
//else  if(ar[1]==0)ot2=0;
if(ar[2]>0 && PORTC.F6==0)ot3=1;
//else  if(ar[2]==0)ot3=0;
if(ar[3]>0 && PORTC.F7==0)ot4=1;
//else  if(ar[3]==0)ot4=0;
blinke=1;
if(ot1==1 || ot2==1 || ot3==1 || ot4==1){
while((PORTC.F4!=ot1 || PORTC.F5!=ot2 || PORTC.F6!=ot3 || PORTC.F7!=ot4) && blinke==1){
if(PORTC.F4==1)ot1=0;
if(PORTC.F5==1)ot2=0;
if(PORTC.F6==1)ot3=0;
if(PORTC.F7==1)ot4=0;
if(ot1==0 && ot2==0 && ot3==0 && ot4==0)blinke=0;
PORTE.F0=ot1;PORTE.F1=ot2;PORTE.F2=ot3;PORTC.F0=ot4;
Delay_ms(500);
PORTE.F0=0;PORTE.F1=0;PORTE.F2=0;PORTC.F0=0;
Delay_ms(500);
  }
 }
}
  chk=0;
  no=0;
  ps=1;
  me=1;
  dcv=0;
  count=1;
  PORTB.F6=0; //Green off
  PORTB.F7=1; //Red on
  Delay_ms(500);
 
//This is the while loop mentioned in my question..i have it commented now..
/*while(i<=3){


  for(;chk<ar;chk++){
  PORTB.F6=0;//Green off
  PORTB.F7=1;//Red on
  Delay_ms(600);
  PORTB.F7=0;
  Delay_ms(600);
  }
  i++;
  if(ar>0){chk=0;}
  PORTB.F6=1;
  Delay_ms(500);
   }*/



move();
// Ihave reenabled the inturrupt register in the 'move' method that i have called here
}
} 
//end of code


can anybody tell me what the problem is? :) :)
 
Last edited by a moderator:

ErnieM

Joined Apr 24, 2011
8,377
First off, seek out the CODE TAG button (that # button top of the text box you typed into). If we can't read your code we can't help you.

Yes, there IS a limit to how many times your interrupt routine can be called. The limit is ONE AT A TIME ONLY.

Your commented while loop contains some 1.7 seconds of delays repeated 3 times. So for 5.1 seconds no other interrupts can fire... and I didn't look at the rest of your code to see all the other delays lurking there.

Generally you want to make your interrupt routine short and sweet, doing the least work possible inside it. You do want to set flags or variables the main loop can test to see what the current state is.

Also, your remark:

Rich (BB code):
move(); // Ihave reenabled the inturrupt register in the 'move' method that i have called here
You don't re-enable interrupts at the end of the IRS: the C compiler does that for you. If you try to do it they get re-enabled before they should be... and you can blow the stack that way because you WILL call the ISR more then the ONE AT A TIME ONLY rule.


And welcome to the forums!
 

Thread Starter

Adb

Joined Aug 24, 2012
2
Thank you very much for your reply,but my problem of not being able to call the interrupt method comes after running the while loop, ie;i cannot call the interrupt method after calling the 'move' method which is called after exiting the while loop...and also i didnt understand what you told about not needing to re-enable the interrupt..don't i have to clear the external interrupt flag bit in my code?(I have done so in the move method which is called here)
and also do you have any suggestions to make my method shorter, as it is longer than the part i have posted :)
Regards, Adb
 

ErnieM

Joined Apr 24, 2011
8,377
don't i have to clear the external interrupt flag bit in my code?(I have done so in the move method which is called here)
You need to clear any and all flags that trigger an interrupt least the interrupt handeler retriggger as you attempt to exit the routine.

You should not touch the interrupt enable flag for the reason stated.

and also do you have any suggestions to make my method shorter, as it is longer than the part i have posted :)
I would need some outline of what work is being performed to have any suggestions.
 
Top