为什么我的轮询例程在中断轮询时不工作,而在主例程上轮询时工作

问题描述 投票:0回答:1

我有一个例程,可以轮询连接在微控制器ATMega328P上的按钮的状态(在芯片上arduino nano,但代码是用C++编写的),例程代码是这样的:

#include <avr/io.h>
#include <avr/interrupt.h>

bool GPIO::GetPressed()
{
     if (bit_is_clear(*this->GetPortOrPin(), this->wichPin)) 
     {
         this->confidenceReleased = 0;                         
     ++this->confidencePressed;
     if (!this->pressed && confidencePressed > thresholdPressed) 
     {
         this->pressed = true;           
         confidencePressed = 0; 
         return true;
     }
     }
    
    else 
    {
        this->confidencePressed = 0; 
            ++this->confidenceReleased;
        if (this->pressed && confidenceReleased > thresholdReleased)
        {
        this->pressed = false; 
        confidenceReleased = 0; 
        }
    }
    return false;
}

如果按下按钮,此方法将返回

true
(这有点复杂,因为存在一些去抖动的情况),否则返回
false

*this->GetPortOrPin()
返回感兴趣的 PINX 寄存器。

当我在

main
内部使用此方法时,效果非常好。

如果我尝试在中断服务例程(由按钮本身触发)上使用相同的方法轮询按钮,则此方法始终返回

false

中断服务程序我的意思是:

ISR (PCINTX_vect) //X can be 1 2 or 3
{
    //i press the button and code makes till this point

    if (somebutton.GetPressed() )
    {
        //never gets inside
    }
}

我尝试在 ISR 内部禁用中断,所以如果弹跳效果在引脚更改时触发大量中断,我可以摆脱这个问题,但这不起作用。

c++ microcontroller interrupt polling atmega
1个回答
0
投票

buttonpressed方法代码的问题在于,如果您在主函数中递归调用它,则在轮询“时尚”中的每次调用中计数器都会增加,如果您在中断例程中调用它,则该函数将仅执行一次并且由于计数器无法达到阈值,输出将始终评估为 false。

© www.soinside.com 2019 - 2024. All rights reserved.