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. |