In this second approach, we write our code in a much more modular fashion. For each binary input, we write a function similar to the following:
void event_a5(unsigned char oldstate, unsigned char newstate)
{
if ((oldstate ^ newstate) & (1 << 5))
{
if (oldstate & (1 << 5))
{
// respond to falling edge
}
else
{
// respond to rising edge
}
}
}
This function, by itself, does not even read any inputs! So, we need some extra code to wrap around it:
newstate = PINA; event_a5(oldstate, newstate); oldstate = newstate;
The code shown above updates the variables newstate and
oldstate. newstate can be an auto (stack allocated)
local variable in a function, while oldstate should be either
a global variable, or a static local variable. This is because
we can potentially invoke the function containing this code
repeatedly by yet another caller.
But wait a minute here, what have we gained with this complicated scheme?
The main advantage of this approach, compared to the previous
polling techinque, is that this code is easily extended. If you want
to handle events for another button connected to pin 6 of port A,
write a subroutine event_a6, and insert a call so you have
newstate = PINA; event_a5(oldstate, newstate); event_a6(oldstate, newstate); oldstate = newstate;The kind of control structure allows the handling of events for each pin to be separated from each other, resulting in cleaner code that is easier to maintain.
To be complete, the entire subroutine (to call event_a5) should
look like the following:
void one_tick(void)
{
static unsigned char oldstate = 0xff;
unsigned char newstate;
// ... whatever code you want to put here
newstate = PINA;
event_a5(oldstate, newstate);
event_a6(oldstate, newstate);
oldstate = newstate;
// whatever code you want to put here
}
Shouldn't this function one_tick be called repeatedly? Yes,
it must be called periodically for the logic to work. You can write
the following code:
while (1)
{
one_click();
}
Besides the fact that you can detect and handle events for multiple input pins, this approach may not seem to be that different from busy polling. However, once we discuss timers and timer interrupts, you will appreciate the strengths of this approach.
Copyright © 2006-02-15 by Tak Auyeung