|
|
View previous topic :: View next topic |
Author |
Message |
Rich_Man
Joined: 05 Dec 2013 Posts: 6
|
ISR problems on 18F8722 -- SOLVED -- BUT NEED SECOND LOOK |
Posted: Thu Dec 05, 2013 12:50 pm |
|
|
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
|
|
Posted: Thu Dec 05, 2013 1:42 pm |
|
|
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
|
|
Posted: Thu Dec 05, 2013 2:02 pm |
|
|
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
|
|
Posted: Thu Dec 05, 2013 2:39 pm |
|
|
You need to debounce your input. Search the forum, discussed a couple of times.
Regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 05, 2013 2:43 pm |
|
|
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 |
|
|
|
|
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
|