Interrupts

Discussion in 'Embedded Systems and Microcontrollers' started by Adb, Aug 24, 2012.

  1. Adb

    Thread Starter New Member

    Aug 24, 2012
    2
    0
    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...

    Code ( (Unknown Language)):
    1.  
    2. void interrupt() {
    3.  
    4. //First inturrupt Directive-Assigning priorities
    5. if(no==1 || ar[0]==0){
    6.  while(PORTC.F3==0 && full==0) {
    7.  
    8.    while(dcv==0 && PORTC.F3==0) {
    9.        PORTD=1;
    10.        x=1;
    11.       if     (PORTB.F2==1){d1=1;dcv=1;}
    12.       else if(PORTB.F3==1){d1=2;dcv=1;}
    13.       else if(PORTB.F4==1){d1=3;dcv=1;}
    14.       else if(PORTB.F5==1){d1=4;dcv=1;}
    15.   }
    16.       if(d1==4)
    17.       y=24;
    18.       else if(d1==3)
    19.       y=18;
    20.       else if(d1==2)
    21.       y=12;
    22.       else if(d1==1)
    23.       y=6;
    24.       //Delay_ms(300);
    25.        //Delay_ms(1000);
    26.    while(dcv==1 && PORTA.F5==0){
    27.     if(PORTB.F1==0) {
    28.     zi=1;
    29.     while(zi==1 && PORTA.F5==0){
    30.    PORTD=2;
    31.   if     (PORTB.F2==1){d2=1;dcv=2;zi=0;}
    32.   else if(PORTB.F3==1){d2=2;dcv=2;zi=0;}
    33.   else if(PORTB.F4==1){d2=3;dcv=2;zi=0;}
    34.   else if(PORTB.F5==1){d2=4;dcv=2;zi=0;}
    35.    }
    36.  
    37.   }
    38.        }
    39.   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
    40.  
    41.         x=0;
    42.  
    43.     if(nfo==0){
    44.       if(dcv==1){
    45.       ar[0]=d1;}
    46.       else
    47.       ar[0]=(((10*d1) + d2)-y);
    48.       }
    49.  
    50.  
    51.     else if(nfo==1){
    52.       if(dcv==1)
    53.       ar[1]=d1;
    54.       else
    55.       ar[1]=(((10*d1) + d2)-y);
    56.       }
    57.  else if(nfo==2){
    58.  if(dcv==1)
    59.  ar[2]=d1;
    60.  else
    61.  ar[2]=(((10*d1) + d2)-y);
    62.  }
    63.  else if(nfo==3){
    64.  if(dcv==1)
    65.  ar[3]=d1;
    66.  else
    67.  ar[3]=(((10*d1) + d2)-y);
    68.    }
    69.   nfo++;
    70.   dcv=0;
    71.   PORTD=10;
    72.   Delay_ms(500);
    73.   }
    74. if(nfo==4)full=1;
    75.  
    76.  
    77.   }
    78. if(ot1==0 || ot2==0 || ot3==0 || ot4==0) {PORTD=6;
    79. if(ar[0]>0 && PORTC.F4==0)ot1=1;
    80. //else if(ar[0]==0)ot1=0;
    81. if(ar[1]>0 && PORTC.F5==0)ot2=1;
    82. //else  if(ar[1]==0)ot2=0;
    83. if(ar[2]>0 && PORTC.F6==0)ot3=1;
    84. //else  if(ar[2]==0)ot3=0;
    85. if(ar[3]>0 && PORTC.F7==0)ot4=1;
    86. //else  if(ar[3]==0)ot4=0;
    87. blinke=1;
    88. if(ot1==1 || ot2==1 || ot3==1 || ot4==1){
    89. while((PORTC.F4!=ot1 || PORTC.F5!=ot2 || PORTC.F6!=ot3 || PORTC.F7!=ot4) && blinke==1){
    90. if(PORTC.F4==1)ot1=0;
    91. if(PORTC.F5==1)ot2=0;
    92. if(PORTC.F6==1)ot3=0;
    93. if(PORTC.F7==1)ot4=0;
    94. if(ot1==0 && ot2==0 && ot3==0 && ot4==0)blinke=0;
    95. PORTE.F0=ot1;PORTE.F1=ot2;PORTE.F2=ot3;PORTC.F0=ot4;
    96. Delay_ms(500);
    97. PORTE.F0=0;PORTE.F1=0;PORTE.F2=0;PORTC.F0=0;
    98. Delay_ms(500);
    99.   }
    100.  }
    101. }
    102.   chk=0;
    103.   no=0;
    104.   ps=1;
    105.   me=1;
    106.   dcv=0;
    107.   count=1;
    108.   PORTB.F6=0; //Green off
    109.   PORTB.F7=1; //Red on
    110.   Delay_ms(500);
    111.  
    112. //[B]This is the while loop mentioned in my question..i have it commented now..[/B]
    113. /*while(i<=3){
    114.  
    115.  
    116.   for(;chk<ar[i];chk++){
    117.   PORTB.F6=0;//Green off
    118.   PORTB.F7=1;//Red on
    119.   Delay_ms(600);
    120.   PORTB.F7=0;
    121.   Delay_ms(600);
    122.   }
    123.   i++;
    124.   if(ar[i]>0){chk=0;}
    125.   PORTB.F6=1;
    126.   Delay_ms(500);
    127.    }*/
    128.  
    129.  
    130.  
    131. move();
    132. // Ihave reenabled the inturrupt register in the 'move' method that i have called here
    133. }
    134. }
    135. //end of code
    136. [/i][/i]


    can anybody tell me what the problem is? :) :)
     
    Last edited by a moderator: Aug 24, 2012
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    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:

    Code ( (Unknown Language)):
    1. move(); // Ihave reenabled the inturrupt register in the 'move' method that i have called here
    2.  
    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!
     
  3. Adb

    Thread Starter New Member

    Aug 24, 2012
    2
    0
    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
     
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    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.

    I would need some outline of what work is being performed to have any suggestions.
     
Loading...