View previous topic :: View next topic |
Author |
Message |
angel
Joined: 19 Oct 2004 Posts: 40
|
#int_ext and #int_timer0 |
Posted: Wed Mar 11, 2009 10:00 am |
|
|
Hi
I would like to use a #int_ext and a #int_timer0.
When I push a button the #int_ext works and inside that interruption I would like to enable or disable the #int_timer0 depending of some conditions.
Does anyone know how to do it? I know the commands enable_interrupts(int_timer0) and disable_interrupts(int_timer0) but I don't know how to manage then in the #int_ext code
Thanks |
|
|
Ttelmah Guest
|
|
Posted: Wed Mar 11, 2009 10:08 am |
|
|
Just use them as normal.
Only thing to remember, is that the interrupt _flag_, will be set if the timer has timed out, while disabled, so unless you want an immediate trigger, when you re-enable it, clear the timer interrupt clear_interrupts(INT_TIMER0), before re-enabling it.
Best Wishes |
|
|
angel
Joined: 19 Oct 2004 Posts: 40
|
the code is.... |
Posted: Thu Mar 12, 2009 2:22 am |
|
|
Hi Telmah. The code of the #int_ext is:
#INT_EXT
void ext_isr(void){
......
if (expre1){
disable_interrupts(INT_TIMER0);
}
if ( expre2){
disable_interrupts(INT_TIMER0);
}else if(expre 3){
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
}else if (expre 4) {
disable_interrupts(INT_TIMER0);
}
Before I have used the function:
void Start_Interruptions () {
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 |RTCC_8_BIT);
set_rtcc(0);
ext_int_edge(0,L_TO_H);
ext_int_edge(1,L_TO_H);
clear_interrupt(INT_EXT);
clear_interrupt(INT_EXT1);
//clear_interrupt(INT_TIMER0);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
//enable_interrupts(INT_TIMER0);//
enable_interrupts(GLOBAL);
}
When I push the button the int_ext works correctly. The first time using the expre nº3 I am able to enable the int_timer0 and the timer0 works but the second time that I try to use the expre nº3 the timer0 it doesn't work.
Do you see any incorrect code? Thanks |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Mar 12, 2009 3:18 am |
|
|
Whenever I read 'button' I also think 'bounce'.
Do you have some kind of key debouncing implemented? This can be done either in hardware or software.
A very good document to read is: http://www.ganssle.com/debouncing.pdf
What really surprised me was how the bounce time was different among the tested switches: from under 1us up to 157ms !! |
|
|
angel
Joined: 19 Oct 2004 Posts: 40
|
yes I have |
Posted: Thu Mar 12, 2009 3:32 am |
|
|
yes I have...
delay_ms(500); // debounce button
I didn't put it before because the button works correctly. The problem is the enable and desable int_timer0 process. It works the first time and then it doent work. |
|
|
Ttelmah Guest
|
|
Posted: Thu Mar 12, 2009 4:37 am |
|
|
This is going to be down to your 'logic' further downstream somewhere...
The enable/disable, 'do what they say on the tin'. However you need to think carefully about what will happen in various circumstances.
For instance, what happens if the button triggers again while the interrupt is already enabled?.
Also, remember, that if you are using delays in the interrupt (general rule, don't, if you can avoid it), interrupts will be disabled in any delays in the 'main' code. Could this be giving your problem?.
There could be any number of problems in the syntax of the expressions being tested.
As a comment though, consider leaving the timer running, and using _it_ to provide the debounce.
So (for instance):
Code: |
int1 do_code=FALSE;
int1 debounce=FALSE;
#int_timer0
void tick(void) {
static int state=0;
if (debounce) {
//Here key has been seen in the INT_EXT, check if it is still true
if (key) {
debounce=FALSE; //Here key is still true - logic will have to suit
//your hardware...
do_code=TRUE;
state=0;
}
else
debounce=FALSE; //No key seen
}
else {
//Now see if I should be running code
if (do_code) {
//Here the key has been seen, and what I 'do', depends on the state
switch (state) {
case 0:
//Here first code after key is seen
state++;
break;
case 1:
//Here second code after key is seen
state++;
break;
case 3:
//Here third code after key is seen
state++;
break;
case 4:
//Extend as far as you need
//If you want to flash LED's etc., do them as
//states here, _but keep each state quick_
//So in one state turn them on, then in the next turn them off etc..
do_code=FALSE;
break;
}
}
}
}
#INT_EXT
void ext_isr(void){
//Then all that needs to happen here, is to tell the timer to check the
//key 'next time round'
set_timer0(0); //Set this to give your required debounce 'period'
clear_interrupts(INT_TIMER0);
debounce=true;
//timer1 should re-test the key next time it executes
}
|
Each 'state', can be kept short, so though the total code is large, the processor gets out of the interrupt quickly each time.
If you want to disable checking the key, when the code is already in the 'do_code' mode, then just test do_code in the EXT interrupt, and don't select 'debounce' if it is true.
Best Wishes |
|
|
angel
Joined: 19 Oct 2004 Posts: 40
|
delay problem |
Posted: Fri Mar 13, 2009 5:00 am |
|
|
hi Ttelmah
Thanks for your help.
I have not finish all I wanted to check but it seems the origine of the problem is the delay_ms command in the int_ext.
I have not checked your program but I have deleted the delay_ms command and the int_timer0 works correctly. The timer0 is working without enabling and desabling it.
Now I need to control the debounce using your program or similar...
Thanks |
|
|
|