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

delay in RB interrupts

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



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

delay in RB interrupts
PostPosted: Sat May 14, 2011 8:54 am     Reply with quote

Dear All, I have a problem in delay routine in RB0 interrupt. I am using the below code:

Code:

#use rtos (timer=0, minor_cycle=100ms)
#use delay(clock = 20000000)

#task(rate=100ms,max=100ms)

void The_first_rtos_task ( )
{
output_high(Pin_D1);
delay_ms(500);
output_low(Pin_D1);
delay_ms(500);

}


#int_RB
void  RB_isr(void)
{
disable_interrupts (int_RB);

if (input(PIN_B4))
 {
     output_HIGH(PIN_D2);
 }
  else
  {   
      delay_ms(3000);
     output_LOW(PIN_D2);
  } 
 
if (input(PIN_B5))
 {
     output_HIGH(PIN_D3);
 }
  else
  {   
      delay_ms(3000);
     output_LOW(PIN_D3);
  }
 
if (input(PIN_B6))
 {
     output_HIGH(PIN_D4);
 }
  else
  {   
      delay_ms(3000);
     output_LOW(PIN_D4);
  }
  enable_interrupts (int_RB);
}

void main()
{
set_tris_A(0xFF);
set_tris_B(0xFF);
set_tris_C(0x80);
set_tris_D(0x01);
set_tris_E(0xFF);


   port_b_pullups(TRUE);
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   ext_int_edge(L_TO_H);
   enable_interrupts(INT_RB);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);


   RTOS_RUN();
   
   

}


The function of this program is very simple. I have a "monitoring led" on pin D0 which is continuously blinking. Now when I press pin B4 "from Low to High", the led lights on and B5 and B6 makes the same. But I need to have a small delay during the release of the button.

I am notice that when I release the B4, 3 seconds will be delay, when I release the B5 there will be a 6 seconds delay and 9 seconds when I release the D6. More than this the compiler is giving me a warning "Interrupts Disabled during call to prevent re-entrancy: (@delay_ms2)

Your help is highly appreciated at this stage and appreciate if you guide me if I am implementing interrupts in the wrong way.

Thanks


Last edited by aaronik19 on Wed Mar 20, 2013 6:36 am; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat May 14, 2011 5:23 pm     Reply with quote

couple of issues...

do NOT use delays inside the ISRs !!

do NOT enable/disable ISR control from within the ISR...

do NOT enable ANY ISR that you do NOT have a handler( routine) for that ISR..

Don't use 'tris..' statements unless you're 100% sure that YOU'VE set the correct bits of the ports. Instead let the compiler handle it for you automatically. A LOT safer and easier, heck that's two reasons WHY you bought the compiler, right ??!!
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Sun May 15, 2011 1:05 am     Reply with quote

thanks temtronic for your tips. So how I can modify this program to work correctly? If I want to make a delay before
Code:
output_LOW(PIN_D2);
how I should make the code? Once again thanks for your help
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun May 15, 2011 2:17 am     Reply with quote

For an exact timing, you would want to start a timer in the RB ISR and perform the delayed pin action in the timer ISR. 3 sec delay is however pretty long. If you don't need the delay accurate up to the ms, a continuous tic timer is probably the better way to schedule timed actions.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Sun May 15, 2011 3:58 am     Reply with quote

Use the RTOS.
When you see the event you want in the RB interrupt, set a global flag, and exit. Nothing else.
Have an RTOS task running perhaps every half second, which _when it sees the flag go true_, clears the flag, and sets a counter to '6'. If when it is called, the counter is non zero, it decrements the counter. When the counter gets to zero, then change the pins you require.

While you are in the interrupt handler _nothing else_ is running. General rule of thumb, is that the interrupt handler should _only_ do the job associated directly with the interrupt, and get out ASAP. If you want a delay, use a hardware timer - as FVM says, (or as you have the RTOS running, this), to generate the delay.

Best Wishes
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Sun May 15, 2011 4:14 am     Reply with quote

thanks for your replies, but I got confused. I used RTOS to blink an LED as an indicator that the processor is running. There are no relationship with the interrupt. Can you please help me to initialize timer inside ISR? Please show a piece of code here at least the basic and I will advance the rest. Once again thanks for your help
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Sun May 15, 2011 3:10 pm     Reply with quote

The RTOS does things at intervals, using a timer. This is the basis of the RTOS. So you can just add an RTOS task, that at an interval, as already described, checks a global flag, and after a certain number of iterations (for the time required), sets the pin you require.
If you want to do it with a separate timer, you don't have to 'initialise timer inside ISR'. You just have a 'tick' event running at some convenient interval, which again monitors global variables to say when it is to do something.

For example, using your existing RTOS task:
Code:

//existing processor setup and RTOS setup here
int8 drop_d2=0;
int8 drop_d3=0;
int8 drop_d4=0;

void The_first_rtos_task (void) {
   static int1 toggle=true;
   static int8 toggle_ctr=0;
   if (toggle_ctr) {
      --toggle_ctr;
   }
   //again don't delay in the RTOS task - it is being called every 100mSec
   else {
      output_bit(Pin_D1,toggle);
      toggle^=1;
      toggle_ctr=4;
   } //this will toggle the pin every five RTOS calls

   //These will do nothing, _until_ the counters are non zero.
   if (drop_d2) {
      --drop_d2;
      if (drop_d2==0) output_low(PIN_D2);
   }
   if (drop_d3) {
      --drop_d3; //decrement only if non zero
      if (drop_d3==0) output_low(PIN_D3);
   }
   if (drop_d4) {
      --drop_d4;
      if (drop_d4==0) output_low(PIN_D4);
   }
}

#int_RB
void  RB_isr(void) {
    //Not needed or wanted disable_interrupts (int_RB);
    if (input(PIN_B4)) {
        output_HIGH(PIN_D2);
    }
    else {   
      drop_d2=30; //Drop in 30 ticks of the RTOS
    }
 
    if (input(PIN_B5)) {
       output_HIGH(PIN_D3);
    }
    else {   
       drop_d3=30;
    }
 
    if (input(PIN_B6)){
       output_HIGH(PIN_D4);
    }
    else {   
       drop_d4=30;
    }
}

//existing main here

The same applies with the RTOS, as with the interrupt handler, but to a lesser extent. Your RTOS call interval, is 100mSec, so you should ensure that the RTOS functions do _not_ take longer than a small fraction of this time, or RTOS accuracy will vanish.

Best Wishes
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