View previous topic :: View next topic |
Author |
Message |
Tester21 Guest
|
Jump out from while on interrupt |
Posted: Wed May 04, 2005 6:25 am |
|
|
Code: | sec=0;
while(sec < 15 && value !=0)
{
printf(lcd_putc,"\f Timeout over ! First option);
delay_ms(200);
}
printf(lcd_putc,"\fSecond option");function();
|
After 15 seconds you get displayed "second option" and this is ok.
What i want to do is to check if the button interrupt
( within this 15 second ) is triggered so i can ( before this 15 seconds timeout ) start with other function.
Instead, im looping in while and the value will never be "1" so i must allways wait till 15 seconds are out...
I must start function on two different ways (either thru timeout or button click, within this timeout)..
John |
|
|
Ttelmah Guest
|
|
Posted: Wed May 04, 2005 7:05 am |
|
|
Code: |
sec=0;
while(sec < 15 && value !=0)
{
printf(lcd_putc,"\f Timeout over ! First option);
delay_ms(200);
if (button()) break;
}
printf(lcd_putc,"\fSecond option");function();
|
Obviously you need a suitable test function (calld 'button' in the example), which returns 'true' when a button is hit, but this will prematurely exit the while, if the condition is met.
Best Wishes |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed May 04, 2005 10:01 am |
|
|
You must set a flag in interrupt (as long as the input you have is capable of requesting an interrupt.)
For example, if I have the button connected to port b pin 0 and have configured the pin for interrupt, I could make an interrupt function:
Code: | ....
int flags;
#bit button_flag = flags.0
#INT_ETX //external interupt port b pin 0 on 16F876A
void button_int(void)
{
button_flag = 1
}
....
sec=0;
button_flag = 0;
while(sec < 15 && value !=0)
{
printf(lcd_putc,"\f Timeout over ! First option);
delay_ms(200);
if(button_flag) break;
}
printf(lcd_putc,"\fSecond option");function();
.... |
Not sure if the interrupt is properly debounced for a button, so a delayed check may be necessary.
Code: | #BYTE port_b = 6
#BIT intr = port_b.0
....
for (i=1;i<100;i++) //insert this in your interrupt before setting flag
{
if(intr == 0) return; //false alarm will return from interrupt without setting flag.
} |
or
Code: | delay_us(25);
if(intr == 0) return; //false alarm will return from interrupt without setting flag. |
should do and would assume a high to cause interrupt. If button is grounded to cause interrupt change to:
Code: | if(intr) return; //false alarm will return from interrupt without setting flag. |
Port b would of coarse have to be initialized for interrupts for rising (button causes high) or falling (button causes low) edges. _________________ -Matt |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
|
Tester21 Guest
|
|
Posted: Thu May 05, 2005 4:44 am |
|
|
I have button (pull up) on connected on port A on A3 and chip is 16F877
On this port there is no external interrupt but i have to trigger it :-(
Wenn i test the program, nothing happens (it's the same as before ).
After timeout is over second option is triggered, but i can't break the timeout.
Code: | //------------------------------------------
#BYTE port_a = 3
#bit button_flag = flags.0
#bit intr = port_a.0
int flags;
#INT_EXT
void button_int(void)
{
button_flag = 1;
delay_us(25);
if(intr == 0) return;
}
sec=0;
button_flag = 0;
while(sec < 15 && value !=0)
{
printf(lcd_putc,"\f Timeout over ! First option);
delay_ms(200);
if(button_flag) break;
}
printf(lcd_putc,"\fSecond option");function();
void main (void)
{
//clear_interrupts(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
}
//-------------------------------------------------- |
Port b would of coarse have to be initialized for interrupts
**
do i get this error becuse of the A3 pin or do i miss this initialisation part
John |
|
|
Tester21 Guest
|
|
Posted: Thu May 05, 2005 4:44 am |
|
|
I have button (pull up) on connected on port A on A3 and chip is 16F877
On this port there is no external interrupt but i have to trigger it :-(
Wenn i test the program, nothing happens (it's the same as before ).
After timeout is over second option is triggered, but i can't break the timeout.
Code: | //------------------------------------------
#BYTE port_a = 3
#bit button_flag = flags.0
#bit intr = port_a.0
int flags;
#INT_EXT
void button_int(void)
{
button_flag = 1;
delay_us(25);
if(intr == 0) return;
}
sec=0;
button_flag = 0;
while(sec < 15 && value !=0)
{
printf(lcd_putc,"\f Timeout over ! First option);
delay_ms(200);
if(button_flag) break;
}
printf(lcd_putc,"\fSecond option");function();
void main (void)
{
//clear_interrupts(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
}
//-------------------------------------------------- |
Port b would of coarse have to be initialized for interrupts
**
do i get this error becuse of the A3 pin or do i miss this initialisation part
John |
|
|
Guest
|
|
Posted: Fri May 06, 2005 11:09 am |
|
|
#INT_EXT can only be used with an external interrupt (pin B0). If you have the button connected to A3, you need to use Ttelmah's method.
Code: | #BYTE port_a = 5
#bit intr = port_a.3
.....
sec=0;
while(sec < 15 && value !=0)
{
printf(lcd_putc,"\f Timeout over ! First option);
delay_ms(200);
if (button()) break;
}
printf(lcd_putc,"\fSecond option");function();
....
short button(void)
{
if(a3 == 1)
{
delay_us(20);
if(a3 == 1);
return(1);
}
return(0);
} |
Would be the way to do it. |
|
|
Guest
|
|
|
Tester21 Guest
|
|
Posted: Sat May 07, 2005 4:27 am |
|
|
Ok. One small thing.. You have defined (a3==1). Is this right sintax or do i have to define some new variable to access intr... ?
John |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sat May 07, 2005 8:47 am |
|
|
Quote: |
Ok. One small thing.. You have defined (a3==1). Is this right sintax or do i have to define some new variable to access intr... ?
|
No. he had defined
#bit intr = port_a.3
Then tryied to acces that pin using:
Code: |
short button(void)
{
if(a3 == 1)
{
delay_us(20);
if(a3 == 1);
return(1);
}
return(0);
} |
which is wrong.
To access such pin:
Code: |
short button(void)
{
if(intr)
{
delay_us(20);
if(intr)
return(1);
}
return(0);
} |
But if you expect that this code will debounce the switch contacts, 20us is not enough.
Depending of the switch you are using, it will still bouncing up to 50ms after toggled.
So if your application is not time sensitive, use a longer delay.
Code: |
short button(void)
{
if(intr)
{
delay_ms(50);
if(intr)
return(1);
else
return(0);
}
} |
You didnīt mention how do you connected the switch, but to run this code it is necesary a pull down
resistor connected between PIN_A3 and Gnd, then your switch connected between PIN_A3 and +5V.
Hope this help you,
Humberto |
|
|
Tester21 Guest
|
|
Posted: Mon May 09, 2005 6:36 am |
|
|
Quote: | You didnīt mention how do you connected the switch |
The first switch is pull up and the second is pull down.
Hardware connection from A3 to gnd:
1.) PIN A3
2.) Resistor ( 50 K )
3.) switch
4.) gnd
----------------------
I compile the program but there is no response on clicking the "A3" button in the timeout part..
John |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon May 09, 2005 6:58 am |
|
|
Donīt understand your description, but this is a pull down. Wire this and before testing any code
-using a scope or a multimeter- whatīs going on with the level in PIN_A3 when you push the button.
Code: |
______________ +5V
|
|
_| ° Button
| °
|
|_____________ PIN_A3
|
|
\
/ R 10K
\
/
|
|
|_____________ Gnd
|
Humberto |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Mon May 09, 2005 2:46 pm |
|
|
Thanks Humberto for the corrections. _________________ -Matt |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Mon May 09, 2005 3:00 pm |
|
|
even better debounce would be:
Code: | short button(void)
{
int cnt;
while(intr)
{
delay_us(5); //
cnt++;
if(cnt == 25)
return(1);
}
return(0);
} |
you should be able to detect a bounce by the time you return. _________________ -Matt |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon May 09, 2005 3:57 pm |
|
|
Hi DragonPIC,
Take in mind that the poster problem was that he canīt detect the pushbutton
action at all and I focused the help in the hardware and not in the best way to
debounce a switch contact.
If you want to know my opinion regarding code for debouncing, by far the best way is
using interrupts:
The level change impossed by the switch action is detected by any of the uC external
hardware interrupts, inside the interrupt clear a global counter and enable one timer,
wich every time it overflows increment the counter, after n counts bit test if the switch
had changed to confirm that the toggle was done, if yes just disable the timer interrupt.
You get a clean and efective debouncing technique without overhead nor wasting
time in delays while you have been running other code in the main.
Best wishes,
Humberto |
|
|
|