a lot of times, you want to read if a pin has gone through a transition (high->low, or low->high). some times, your mcu may have interrupt-on-change functionality for that.
for those mcus that do not have IOC functionality, or you don't have space for IOC, you can implement it fairly easily, as shown below.
=========code===============
#define PORT_TYPE unsigned int //works for 32-bit ports
//#define PORT_TYPE unsigned char //works for 8-bit ports
//set bits where the pins have gone through a low-high or high-low transition
PORT_TYPE port_get_changing(PORT_TYPE port, PORT_TYPE pins) {
PORT_TYPE tmp;
static PORT_TYPE pins_prev=0x00;
tmp=pins_prev; //save pins_prev
pins_prev=port & pins; //read pins from port
return (pins_prev ^ tmp); //return rising or falling edge
}
//return 1 on bits where the pins have gone through a high-low transition
PORT_TYPE port_get_falling(PORT_TYPE port, PORT_TYPE pins) {
PORT_TYPE tmp;
static PORT_TYPE pins_prev=0x00;
tmp=pins_prev; //save pins_prev
pins_prev=port & pins; //read pins from port
return (pins_prev ^ tmp) & tmp; //return falling edge
}
//set bits where the pins have gone through a low-high transistion
PORT_TYPE port_get_rising(PORT_TYPE port, PORT_TYPE pins) {
PORT_TYPE tmp;
static PORT_TYPE pins_prev=0x00;
tmp=pins_prev; //save pins_prev
pins_prev=port & pins; //read pins from port
return (pins_prev ^ tmp) & pins_prev; //return rising edge
}
===========end of code============
port_get_rising(port, pins) will return 0x08 if port.7 has gone through a low->high transition.
similarly, port_get_changing(port, pins) will return 0x28 if port.9 and port.7 have gone through either a high->low or low->high transition.
here is a piece of code that demonstrates how it works.
=====demo code===========
//demo program
int main(void) { //main
mcu_init();
while (1) {
if (port_get_changing(KEY_PORT, KEYs) & KEY1) IO_FLP(LED_PORT, LED1); //flip led1 where key1 has changed
if (port_get_falling(KEY_PORT, KEYs) & KEYs) IO_FLP(LED_PORT, LED2); //flip led2 when key1 or key2 goes high->low
if (port_get_rising(KEY_PORT, KEYs) & KEY2) IO_FLP(LED_PORT, LED3); //flip led3 when key2 goes low->high
//do something else
}
}
=========end code==========
KEY1 and KEY2 are two input sources that go from 0->1 and then 1->0 at varying frequencies.
LED1 is programmed to flip its state whenever KEY1 has gone through a transition;
LED2 flips if either KEY1 or KEY2 goes from high to low;
LED3 flips only if KEY2 goes low->high.
here is the simulation.
(原文件名PC2106 get_key.PNG)
since the code is entirely C, it is highly portable to other platforms.
enjoy. |