Interrupt Handling (pushbuttons)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Interrupt Handling (pushbuttons)

4,237 Views
kaiki
Contributor I
I have a circuit built around the HCS08 and I need to handle 3 specific events.
The first 2 are push events from 2 pushbuttons connected to Port A (pins 6 and 7)
and the third is an interrupt from an external chip that signals the micro that its done its work.

Here's how I initalize the registers :

// Enable interrupt on KBI (portA)
KBI1SC_KBI1E = ENABLED;

// enable pullups
PTAPE_PTAPE4 = ENABLED;
PTAPE_PTAPE6 = ENABLED;
PTAPE_PTAPE7 = ENABLED;

// Direction in (0)
PTAPE_PTAPE4 = IN;
PTAPE_PTAPE6 = IN;
PTAPE_PTAPE7 = IN;

// enable int on 3 pins
KBI1PE_KBI1PE4=ENABLED;
KBI1PE_KBI1PE6=ENABLED;
KBI1PE_KBI1PE7=ENABLED;

The vector table is set like so :
kbd_isr, /* vector 22: KBI */

// here is the interrupt handler
interrupt void kbd_isr (void)
{
// if its really a KBI event
if (KBI1SC_KBF)
{
// don't allow more kbi interrupts
KBI1SC_KBI1E = DISABLED;

// clear interrupt flag
KBI1SC_KBACK = 1;

// make sure everyone knows theres a KBI event
SETBIT(KBI_EventFlag, KBI_EVENT_PENDING);
}
}

basically in the ISR I'm only setting a flag asking the app to take it from there.
In the app I'm expecting that the specific pin that fired the event should have a 1 on its data line and so if I check PTAD_PTAD{4,6,7} i should know if the interrupt happened. But I don't get anything on the data line.
Question 1 : Should I get data on this pin everytime an interrupt is fired?

as a temporary workaround I use this code (right now I pretty much know when which event is going to fire)


void HandleKBIEvent(void)
{
// make sure it was a valid call
if(GETBIT(KBI_EventFlag, KBI_EVENT_PENDING))
{
// chip shouldn't have a debounce period
if (CHIP_INT_INT == ENABLED)
SETBIT(KBI_EventFlag,KBI_EVENT_CHIP);
else
{
// debounce for switches
delay_ms(500);
if(BUTTON1_INT == ENABLED)
SETBIT(KBI_EventFlag,KBI_EVENT_BTN1);
else if(BUTTON2_INT == ENABLED)
SETBIT(KBI_EventFlag,KBI_EVENT_BTN2);
}

// clear event
CLRBIT(KBI_EventFlag, KBI_EVENT_PENDING);
// we took care of this
SETBIT(KBI_EventFlag,KBI_EVENT_HANDLED);

// reenable interrupts
KBI1SC_KBI1E = ENABLED;
}
}

Question 2: The interrupts on the pushbutton lines don't always fire. Although I can see with an analyzer that the line does go low. Any idea why this might happen?

Thanks,
K
Labels (1)
0 Kudos
Reply
2 Replies

641 Views
byteybird
Contributor I
One of your inputs is from an external device that signals when an event is finish. This signal probably does not require any debouncing. Have you consider bring this into one of the external interrupts?

The keyboard logic requires that all enable signals be logic high for an interrupt to be asserted when any one of the lines goes low. In the keyboard interrupt handler, determine which input fire the interrupt and disconect that input from the keyboard logic. This will then allow the other pushbutton(s) to asset an interrupt.

I would not use a delay function for debouncing. In your main loop use a polling technique and check the line for a logic high state. Put a variable counter and verify that its high again for a certain number of consecutive looks (threshold), before that pin is re-enable again as a keyboard interrupt. Or setup the timer to assert an interrupt at some high rate and perform the logic test in the timer interrupt handler; or set a flag in the timer interrupt handler and perform the test in a main loop when the above flag is set.

What I found in my logic is that when a I/O was enabled as a keyboard interrupt, I had to make the corresponding I/O pin be an output to keep a false interrupt from occurring.
0 Kudos
Reply

641 Views
bigmac
Specialist III

Hello Kai,

Have you checked that the KBI triggering edge matches the push event, rather than the release event, for the pushbuttons?  With a single push, both events can occur because of switch bounce, so a mismatch may not be obvious.

I notice that you disable all further KBI interrupts until 500ms de-bounce delay is complete. So no other events could be detected within this period.  I would suggest that you disable only the particular pushbutton input that caused the current interrupt, so that other interrupt events can be detected.  Allowing 500ms de-bounce is probably excessive - normally 50-100ms is enough for small pushbuttons.

Regards,

Mac

 

0 Kudos
Reply