View previous topic :: View next topic |
Author |
Message |
waheed
Joined: 19 May 2012 Posts: 26 Location: Pakistan
|
External Interrupt Problem |
Posted: Wed May 23, 2012 4:22 am |
|
|
Controller: 18f452
I have written simple program to test the external interrupt but it doesn't work. Kindly help.
Code: |
#include <18F452_new.h>
#fuses NOWDT,HS,NOPROTECT
#use delay(clock=20000000)
#int_ext
void ext_isr()
{
if (!input(PIN_B0))
{
output_low(PIN_C7);
}
}
void main()
{
EXT_INT_EDGE(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(global);
while(1)
{
output_high(PIN_C7);
}
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed May 23, 2012 5:08 am |
|
|
Always post your compiler version number!
How do you know it doesn't work? Describe the actions you take and the results you see (or don't see).
I assume you are looking to a LED or something similar connected to C7? If yes, then how many microseconds do you think it will take for the output to be set high again by the main loop? ... |
|
|
waheed
Joined: 19 May 2012 Posts: 26 Location: Pakistan
|
|
Posted: Wed May 23, 2012 5:19 am |
|
|
Compiler: v4.120
Yes, I am looking at an LED connected to C7.
I guess the main function sets the output high again before I can notice it.
Is it possible that LED remains low until I release the button and I have to use the interrupt? |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1349
|
|
Posted: Wed May 23, 2012 6:14 am |
|
|
The interrupt fires on the transition from high to low. You need to consider using a flag variable in your interrupt to indicate it fired, and then, in your main while loop check to see if the flag is set. If it is, have the loop delay a few seconds and then set the line back high.
The way you have it now, the line will only be low for an instant. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Wed May 23, 2012 8:12 am |
|
|
Are you _asking_ if 'you have to use the interrupt', or saying that you have to?.
Consider:
Code: |
#include <18F452_new.h>
#fuses NOWDT,HS,NOPROTECT
#use delay(clock=20000000)
#int_ext
void ext_isr(void) {
if (input(PIN_B0)==0) { //Possibly just slightly 'clearer' than using not
EXT_INT_EDGE(L_TO_H);
output_low(PIN_C7);
}
else {
EXT_INT_EDGE(H_TO_L);
output_high(PIN_C7);
}
}
void main(void) {
output_high(PIN_C7); //Start with the LED off
EXT_INT_EDGE(H_TO_L);
clear_interrupts(INT_EXT); //The act of changing the active edge
//can result in the interrupt being triggered
enable_interrupts(INT_EXT);
enable_interrupts(global);
do {
//Do whatever else you want
} while(TRUE);
}
|
Best Wishes |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed May 23, 2012 11:27 am |
|
|
How about something very basic:
Code: | #int_ext
void ext_isr(void)
{
output_toggle(PIN_C7);
}
void main()
{
EXT_INT_EDGE(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(global);
while(1)
{
;
}
}
|
This will simply toggle the output each time the interrupt is triggered.
Ronald |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Wed May 23, 2012 2:45 pm |
|
|
But then (of course) he would have to push the button twice.
Best Wishes |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 23, 2012 4:22 pm |
|
|
Depends how clean switch contact is.
May bounce several times on make/break.
Probing external input pin, and LED pin with a decent digital 'scope, will answer all the questions.
Mike |
|
|
hoangkhuong
Joined: 16 Mar 2012 Posts: 31
|
|
Posted: Wed May 23, 2012 7:36 pm |
|
|
Did you set the pin connect to the button as input ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 23, 2012 10:35 pm |
|
|
What is your button circuit ? It should look like this:
Code: |
+5v
|
<
> 4.7K
< ___ Switch
To | _|_|_
PIC -----------------o o------
pin |
--- GND
-
|
This circuit holds the pin at a Logic "1" state normally. When you push
the button, the pin goes to a "0" state. When you release it, the pin
goes back to the "1" state. There will be some "bounce" (noise),
mostly after the falling edge, when you press the button. Depending
on the type of push-button switch, the bounce could be for a few tens
of microseconds, or possibly several milliseconds for a poor quality switch. |
|
|
waheed
Joined: 19 May 2012 Posts: 26 Location: Pakistan
|
|
Posted: Wed May 23, 2012 11:41 pm |
|
|
Many Thanx to all for all the replies..
Ttelmah:
Your Code is exactly what I was looking for.
Quote: |
Depends how clean switch contact is.
May bounce several times on make/break.
Probing external input pin, and LED pin with a decent digital 'scope, will answer all the questions.
|
Switch Bounce is the least of my concerns at present. The program runs fine without it till now. But, surely, I 'll take care of it afterwards.
Yes, My Input Button is Active Low. |
|
|
waheed
Joined: 19 May 2012 Posts: 26 Location: Pakistan
|
|
Posted: Thu May 24, 2012 7:16 am |
|
|
Can Multiple interrupts (EXT, EXT1,EXT2) be used in a similar way?
Controller used is 18f452.
I have tried doing this but only the "EXT" works.
EXT1 and EXT2 ISRs toggle the LED at Pins C6 & C5 respectively. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu May 24, 2012 8:11 am |
|
|
Yes.
Thing that needs to change, is the edge selection code.
Needs to have the interrupt number involved added:
Code: |
#int_ext1
void ext1_isr(void) {
if (input(PIN_B0)==0) { //Possibly just slightly 'clearer' than using not
EXT_INT_EDGE(1,L_TO_H);
output_low(PIN_C7);
}
else {
EXT_INT_EDGE(1,H_TO_L);
output_high(PIN_C7);
}
}
|
Note the 1's added - 2's for ext_2.
Seriously, consider an alternative.
Look at the portB changed ISR. This is available on the top four bits of portB, if any of them _change_. No fiddling with altering ISR directions etc..
You can use the input_change function to find out which bit(s) have changed, and according to the levels turn on/off the corresponding LED.
Best Wishes |
|
|
|