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

Panic Button Application

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



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

Panic Button Application
PostPosted: Fri Sep 04, 2020 9:51 am     Reply with quote

Hey guys, I thougt of a panic button for a card I built. I want to stop the program there whenever button is pressed and continue on second press. What is most efficient way to implement this? I'm thinking using ext_int and make it stuck in it. and hoping PIC won't reset in there since wdt is off.
Would something like this work?
Code:

#INT_EXT HIGH CLEAR_FIRST
void ext_int_routine(void){
  static int1 ext_int_flag=0;
  ext_int_flag=!ext_int_flag;
 
  while(ext_int_flag){
    delay_cycles(1);
  }

}


And also there will be timer interrupts too in working code, so I'm planning to save timer values and stop timers in this function, also reload and restart them on second press.
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Sep 04, 2020 10:51 am     Reply with quote

Naked sure you add some form of hardware debounce to the button. Small
capacitor across it. Otherwise you have almost certainty that it will
trigger multiple times.
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Tue Sep 08, 2020 3:06 am     Reply with quote

Yes you surely right, I already have installed debounce parts beforehand.
I tried the code I mentioned but it is not working, it seems allergic to while loop in an interrupt routine. Code stops working completely on start. But if I comment out while lines from routine, then it works ok.
So it seems I can not get the code to stuck in an interrupt routine.

Can I have some advice ? How can I pause/unpause a program using a button connected to RB0?
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Sep 08, 2020 4:14 am     Reply with quote

No, the problem is it can never get out.

Think about it. First time the interrupt fires, ext_int_flag is zero.
Gets set to 1 (so now TRUE). Starts looping. How is it ever going to exit?.....

What you need is:
Code:

#INT_EXT HIGH CLEAR_FIRST
void ext_int_routine(void){
  static int1 ext_int_flag=0;
  ext_int_flag=!ext_int_flag;
 
  while(ext_int_flag)
  {
     if (interrupt_active(INT_EXT)) //interrupt has triggered again
        return; //exit the interrupt if so (this will mean code will be called again
  }
}


Understand, interrupts are not called inside other interrupts. So sitting
inside a loop inside the interrupt, nothing except a reset will get you out.
Hence you have to write an 'exit route' from the interrupt.
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Tue Sep 08, 2020 1:30 pm     Reply with quote

Well, but I thought CLEAR_FIRST option does that trick by clearing interrupt flag before entering the function. So I thought interrupt could be fired again since flag is cleared. And so, if button is pressed second time and when routine is called again, ext_int_flag toggled to 0 again.
Or at least that was what I hoped for Rolling Eyes
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 12:59 am     Reply with quote

The CLEAR_FIRST clear the interrupt, so yes, it will re-trigger, but the
handler cannot be called, since you are already inside the handler.
The chip does not support 're-entrancy' (where a routine is called inside
itself). Hence as I show, you can test for the interrupt being re-triggered,
and exit the routine (which will then result in the routine being called
again).
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 4:51 am     Reply with quote

Unfortunately still not working, I tried many ways I could think of like do-while loop, while looop, if-goto loop and for loop. I checked interrupt flag as loop breaker in them but none of them are worked.
Program does not start as soon as I changed normal loop to a possible infinite loop in code. For example;
This is not doing anything useful but code starts and works with this
Code:
#INT_EXT HIGH CLEAR_FIRST
void ext_int_routine(void){
   clear_interrupt(INT_EXT);
   static int1 ext_int_flag=0;
   ext_int_flag=!ext_int_flag;
   if(ext_int_flag){
      for(int8 looper=0;looper<2;looper++){
         delay_cycles(1);
      }
   }
}


But after changing it to a possible infinite loop, this code does not start.

Code:
#INT_EXT HIGH CLEAR_FIRST
void ext_int_routine(void){
   clear_interrupt(INT_EXT);
   static int1 ext_int_flag=0;
   ext_int_flag=!ext_int_flag;
   if(ext_int_flag){
      for(int8 looper=0;looper<2;looper++){
         delay_cycles(1);
         if(!interrupt_active(INT_EXT)){
            looper=0;
         }else{
            break;
         }
      }
   }
}

So, I tried but it seems like compiler really dont want a code that possibly would stay in an interrupt routine. I stopped trying this and used another way compitable with my main code to pause the program.

But I still wonder if it was possible.
Ah, another thing I thought of about pausing the flow of program is; adding an infinite loop in to program which can not be called normally and swapping it's line number and saved program counter on interrupt routine. Unfortunately I dont know how to get line numbers and could not try it but I would like to know if anyone knows.
_________________
There is nothing you can't do if you try


Last edited by elcrcp on Wed Sep 09, 2020 7:17 am; edited 1 time in total
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 5:50 am     Reply with quote

How long is your main loop time?
If your total main loop time is 100ms for example, and the process being controlled is not super fast, you can set a flag and then call a function on the main code with the waiting loop.

Basically your maximum time from button press to full stop will be a maximum of 100ms... this would work for filling a water tank, not so much for protecting a finger in a band saw or an airbag in a car.

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 7:30 am     Reply with quote

Gabriel wrote:
How long is your main loop time?
If your total main loop time is 100ms for example, and the process being controlled is not super fast, you can set a flag and then call a function on the main code with the waiting loop.

Basically your maximum time from button press to full stop will be a maximum of 100ms... this would work for filling a water tank, not so much for protecting a finger in a band saw or an airbag in a car.

G.

No no, it is not about a especial program I was looking for a general way. I did find a way to pause my main loop but what I was looking was to halt the program at anywhere of the program and contiue from there.
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 7:32 am     Reply with quote

I just tested this on a debug board, and it runs perfectly.
Code:

#include <18F4520.h>
#device ADC=10
#device HIGH_INTS=TRUE
#FUSES NOWDT                   
#use delay(crystal=20000000)
//basic test setup
#use RS232(UART1, baud=9600, ERRORS)

#INT_EXT HIGH CLEAR_FIRST
void ext_int_routine(void){
   static int1 ext_int_flag=FALSE;
     
   ext_int_flag=!ext_int_flag;
   if (ext_int_flag)
   {
      for(int8 looper=0;looper<2;looper++)
      {
         delay_cycles(1);
         if(!interrupt_active(INT_EXT))
         {
            looper=0;
         }
         else
         {
            return;
         }
      }
   }
}   

void main()
{
   setup_adc_ports(NO_ANALOGS, VSS_VDD);
   if (interrupt_active(INT_EXT))
      clear_interrupt(INT_EXT);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   while(TRUE)
   {
      printf("In main\n");
      delay_ms(500);
   }
}
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 9:52 am     Reply with quote

Ttelmah wrote:
I just tested this on a debug board, and it runs perfectly.
Code:


>>   if (interrupt_active(INT_EXT)) <<
>>      clear_interrupt(INT_EXT); <<



So this was the missing key Rolling Eyes it written in manual that you need to use clear_interrupt() in code but I was using it in interrupt routine. It actually needed before enabling interrupt. Now it is working. Thanks a lot
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 10:00 am     Reply with quote

That's actually a 'read the data sheet' one.
It warns you there that depending on how the signalling is sequenced.
the external interrupt may be set at boot.... Very Happy
jeremiah



Joined: 20 Jul 2010
Posts: 1314

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 10:41 am     Reply with quote

You probably don't even need the IF before the clear. Just clear it. If the interrupt is active, then it will clear it. If the interrupt is already clear, the clear_interrupts doesn't waste more time than doing the IF followed by the branch instruction.

Last edited by jeremiah on Wed Sep 09, 2020 11:00 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Sep 09, 2020 10:49 am     Reply with quote

Dead right.
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