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

ISR problems on 18F8722 -- SOLVED -- BUT NEED SECOND LOOK

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



Joined: 05 Dec 2013
Posts: 6

View user's profile Send private message

ISR problems on 18F8722 -- SOLVED -- BUT NEED SECOND LOOK
PostPosted: Thu Dec 05, 2013 12:50 pm     Reply with quote

I'm writing a test program to register button pushes. I'm using the INT_EXT interrupts on the PIC18F8722. My problem is that I don't always see a button push or a button release, and when I do it doesn't always indicate the correct condition. That is some times the program will say 'Button UP' on a button release and visa-versa. This is my first time using interrupts, so any explanations are welcome. below is the code.

Code:

#include <18f8722.h>
#fuses HS,NOLVP,NOWDT
#device ICD=TRUE
#use delay(clock=20000000)

#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(master, sda=PIN_C0, scl=PIN_C1)


short int button1, button2;

// ***** ISR for PIN_B1 edge *****
#int_ext1
void int_ext1_isr(void)
{
   button1 = 1;
}

// ***** ISR for PIN_B2 edge *****
#int_ext2
void int_ext2_isr(void)
{
   button2 = 1;
}


void main()
{
// ***** setup interrupts for B1 & B2 *****
enable_interrupts(INT_EXT1);
enable_interrupts(INT_EXT2);

clear_interrupt(INT_EXT1);
clear_interrupt(INT_EXT2);

enable_interrupts(GLOBAL);


printf("program is running now....\r\n");
int32 result;

// ***** Start Continous Loop *****
while(TRUE)
{
   // if button PIN_B1 is pressed
   if(button1)
   {
      // read pin to see if up or down
      result = input(PIN_B1);
      if(!result) printf("button 1 DOWN\r\n");
      if(result)  printf("button 1 up\r\n");
      button1 = 0;
   }
   // if PIN_B2 is pressed
   if(button2)
   {
      // read pin to see if up or down
      result = input(PIN_B2);
      if(!result) printf("button 2 DOWN\r\n");
      if(result)  printf("button 2 up\r\n");
      button2 = 0;
   }
}
// ----- End Loop -----
}


These are the relevant Enable/Disable_interrupts constants in the 18f8722 header file.
#define INT_EXT1_L2H 0X5001F008
#define INT_EXT1_H2L 0X6001F008
#define INT_EXT1 0X00F008
#define INT_EXT2_L2H 0X5001F010
#define INT_EXT2_H2L 0X6001F010
#define INT_EXT2 0X00F010


Last edited by Rich_Man on Thu Dec 05, 2013 2:04 pm; edited 1 time in total
Rich_Man



Joined: 05 Dec 2013
Posts: 6

View user's profile Send private message

PostPosted: Thu Dec 05, 2013 1:42 pm     Reply with quote

I added a delay_ms(10) before the read pin statement:
Code:

   if(button1)
   {
      // read pin to see if up or down
      delay_ms(10);
      result = input(PIN_B1);
      if(!result) printf("button 1 DOWN\r\n");
      if(result)  printf("button 1 up\r\n");
      button1 = 0;
   }


Now I never get an incorrect condition. When the program says the button is up it is up and when it says it's down it's down.
They only remaining problem is that it only sometimes triggers on a button down event, but always triggers on a button up event. I think I know why.
I looked at the signal on an Oscope and it jumps wildly from 5V-0V on a button press. I believe that the ISR is not to trigger on a button down (H2L event), but because the signal jumps back and forth, a button down is actually triggering an L2H event.

Could someone with experience verify this, and offer a solution? THANKS
Rich_Man



Joined: 05 Dec 2013
Posts: 6

View user's profile Send private message

PostPosted: Thu Dec 05, 2013 2:02 pm     Reply with quote

I think I have it fixed. couldn't figure it out after hours of trying, and 15min after posting the question I got it.

I set the interrupt to trigger on a button down. While handling the button down ISR is set the interrupt to trigger on a button up. So, after a button down it looks for a button up.

Any explanations or additional information would be appreciated.

Code:

#include <18f8722.h>
#fuses HS,NOLVP,NOWDT
#device ICD=TRUE
#use delay(clock=20000000)

#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(master, sda=PIN_C0, scl=PIN_C1)


short int button1, button2;

// ***** ISR for PIN_B1 edge *****
#int_ext1
void int_ext1_isr(void)
{
   button1 = 1;
}

// ***** ISR for PIN_B2 edge *****
#int_ext2
void int_ext2_isr(void)
{
   button2 = 1;
}


void main()
{
// ***** setup interrupts for B1 & B2 *****
   // set to trigger on button down event //
enable_interrupts(INT_EXT1_H2L);
enable_interrupts(INT_EXT2_H2L);

clear_interrupt(INT_EXT1);
clear_interrupt(INT_EXT2);

enable_interrupts(GLOBAL);


printf("program is running now....\r\n");
int32 result;

// ***** Start Continous Loop *****
while(TRUE)
{
   // if button PIN_B1 is pressed
   if(button1)
   {
      // read pin to see if up or down
      delay_ms(10);
      result = input(PIN_B1);
      if(!result)
      {
            // set to trigger on button up event //
         enable_interrupts(INT_EXT1_L2H);
         printf("button 1 DOWN\r\n");
      }
      if(result)
      {
            // set to trigger on bgutton down event //     
         enable_interrupts(INT_EXT1_H2L);
         printf("button 1 up\r\n");
      }     
      button1 = 0;
   }
   // if PIN_B2 is pressed
   if(button2)
   {
      // read pin to see if up or down
      delay_ms(10);
      result = input(PIN_B2);
      if(!result)
      {
            // set to trigger on button up event //
         enable_interrupts(INT_EXT2_L2H);
         printf("button 2 DOWN\r\n");
      }
      if(result)
      {
            // set to trigger on bgutton down event //     
         enable_interrupts(INT_EXT2_H2L);
         printf("button 2 up\r\n");
      }     
      button2 = 0;
   }
}
// ----- End Loop -----
}
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Thu Dec 05, 2013 2:39 pm     Reply with quote

You need to debounce your input. Search the forum, discussed a couple of times.

Regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 05, 2013 2:43 pm     Reply with quote

Quote:
I looked at the signal on an Oscope and it jumps wildly from 5V-0V on a button press.

This is called contact "bounce". The various ways of fixing it, in hardware
or software, are called "debouncing". To research this, you can
use Google to search for:

Quote:
site:microchip.com/forums external interrupt bounce OR debounce

or
Quote:
site:ccsinfo.com/forum external interrupt bounce OR debounce


There are other ways to do it. I prefer to use a 10ms timer tick to poll
the switches. Then you can use any i/o pins. You're not confined to the
external interrupt pins.

See this post on the button command. It has a link to timer interrupt
code that polls the buttons:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837
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