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

External Interrupt Buffer?

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



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

External Interrupt Buffer?
PostPosted: Thu May 10, 2007 4:54 pm     Reply with quote

I have a button connecting to the external interrupt on a PIC18F1320 and my debounce routine works great on the downpress - no detection of any bouncing. Unfortunately, the PIC is fast enough that it always seems to pick up the release of the button - even when I minimize clockspeed at 31kHz. The strange thing is that I have the external_edge set to H_TO_L since my button is active low so this should not detect the release... I only want detection of the downpress so this is incredibly frustrating. As you can see from the code I even set the interrupt to be off for ~250ms after each press - far longer than it should take the user to press and depress the button yet it STILL picks up the release :( and the update is really slow on the LCD like it actually is buffering the interrupts. So anyhow, any help would be greatly appreciated!

Here is my code:

Code:

include <18F1320.h>
#device adc=10
#fuses NOWDT,NOPROTECT,NOLVP,NOMCLR,INTRC_IO //CCPBO
#use delay(clock=31000)
#include "LCDD.c"

boolean update = false;
boolean released = false;
boolean pressed = true;
boolean peakfound = true;
boolean firstread = false;
boolean debounced = false;

#int_ext
void move_down()
{
      disable_interrupts(INT_EXT);
      presses++;
      update = true;
      set_timer1(62000);
}

#int_timer1
void peak_finder()
{
   enable_interrupts(INT_EXT);
}

void main()
{
   lcd_init();
   setup_timer_1(T1_INTERNAL);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_EXT);
   ext_int_edge(H_TO_L);
   enable_interrupts(global);
   set_tris_b(11111111);
   port_b_pullups(00000001);

   while(1)
   {
      if (update)
      {
         printf(lcd_putc, "\fPresses: %Lu", presses);
         update = false;
      }
   }
}

Sad Sad Sad Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 10, 2007 5:02 pm     Reply with quote

Clear the External interrupt flag before you enable (or re-enable) external interrupts.

Example:
Code:

clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Thu May 10, 2007 5:12 pm     Reply with quote

Thanks PCMProgrammer - Works better although still only about 95% effective. Once in awhile on the release it will still detect an interrupt. May this be unavoidable without a debounce circuitry on the port?
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu May 10, 2007 5:36 pm     Reply with quote

Firing the timer1 you are nulling only the first bounces, but not the bounces
generated when you release the pushbutton.

Try this:
Code:

#int_ext
void move_down()
{
      disable_interrupts(INT_EXT);
      presses++;
      update = true;
      do{}while(!PIN_B0);
      set_timer1(62000);
}



Humberto
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Thu May 10, 2007 6:02 pm     Reply with quote

Thank you Humberto, I understand what you're going for but I tested it and this didn't work. I believe the reason to be that this while loop will be exited immediately upon the first bounce even before the timer has a chance to debounce. So, when the button is released it simply bounces again several times and the loop doesn't do it's trick. The problem here is that upon release we get several bounces and the first one triggers the ISR before the timer1 can debounce it. Seems like this situation is unfortunately unavoidable without a hardware debouncer since there is no way to know exactly how long the user will be pressing the button. Any other ideas?
libor



Joined: 14 Dec 2004
Posts: 288
Location: Hungary

View user's profile Send private message

PostPosted: Thu May 10, 2007 7:29 pm     Reply with quote

If you can afford a 50 ms latency I suggest to retest the input after 50ms and neglect the change if the input is not still low after the bouncing ended. As a by-effect any press shorter than 50ms (glitch, interference, etc) will also be neglected.
If you cannot afford staying in the isr so long, you can also do the retest in the timer isr to let your main code run. You can tune the delay to any optimum value you need.
Code:
#int_ext
void move_down()
{
      delay_ms(50);
      if (PIN_B0) return;
      presses++;
      update = true;
}
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu May 10, 2007 9:13 pm     Reply with quote

The bounce problem at release time can be cancelled in this way, it doesn´t need any timer.
Code:

#int_ext
void move_down()
{
int bounces;
   
      disable_interrupts(INT_EXT);
      bounces = 250;
      presses++;
      update = true;
      do
        { delay_us(400);  // you can trimm this value
          if(!PIN_B0)
            { bounces = 250;}
          else
            { bounces--;}
        } while(bounces);
}

//  in main() 
  while(1)
   {
    if(update)
      {
        printf(lcd_putc, "\fPresses: %Lu", presses);
        update = false;
        delay_ms(200);
        enable_interrupts(INT_EXT);           
      }
   }



Not tested nor tunned, I´m not in my job right now.


Humberto
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