查看: 1700|回复: 0
打印 上一主题 下一主题

Reading falling / rising edges without using interrupt on change

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-9 20:41:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


电梯直达[url=][/url]
1楼
发表于 2010-7-28 08:26:02 | 只看该作者


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.




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表