【发布时间】:2021-02-22 19:08:31
【问题描述】:
我正在使用 STM32 NUCLEO-F401RE 微控制器板。
我有一个扬声器,可以在向上/向下推动操纵杆时按设定的量改变频率。我的问题是,有时(通常情况下)当向上/向下推动操纵杆时,频率会多次增加/减少,这意味着 ISR 正在执行多次。此外,InterruptIn 对象设置为在上升沿触发,但有时它也会在下降沿执行(当向上/向下推动操纵杆返回中性时)。有什么帮助可以克服这个问题吗?
void upISR()
{
if (greenLED.getStatus())
{
myTicker.detach();
frequency+=200;
myTicker.attach(callback(&spkr, &Speaker::toggle), 0.5/frequency);
}
}
'
int main()
{
InterruptIn up(A2);
InterruptIn down(A3);
InterruptIn fire(D4);
up.rise(&upISR);
down.rise(&downISR);
fire.rise(&toggleISR);
redLED.on();
while (1){}
}
【问题讨论】:
-
这是一个经典的问题,请阅读“去抖动”(开关去抖动,按钮去抖动)
-
@BenVoigt 我读过的很多内容都很好地描述了这个问题,然后只提出了一些令人震惊的糟糕的软件解决方案。很少有人处理直接触发中断的开关,解决方案不适合在中断上下文中使用。 OP 应该如何将好的建议与坏的建议(或可能适用于或不适用于这种情况的建议)进行分类?最好在这里发布一个答案并让社区来衡量其质量 - 当然只计算合法投票 ;-)。
-
@Clifford:因为虽然“非常糟糕”对任何情况都不利,但在一种情况下的“好”解决方案也不能解决所有情况。仅根据 OP 在问题中提供的信息,我无法给出完整的答案……还有一些示波器轨迹和开关与 MCU 之间的连接示意图会有所帮助。
-
您通常不希望在开关状态更改时中断,这很少奏效。一种选择是基于定时器的中断并定期对开关进行采样并获取您获得的值并使用它。另一个是一个过滤器,它基本上以某种形式对开关状态进行过采样,并在一个级别连续查找 X 或对其应用数学以消除故障,16 个中有 15 个处于同一级别,等等。每次重新开始采样时设置在中间,如果它达到阈值有足够的 1 或 0 等...
-
它很简单,因为你有一个正常(未推送)状态和一个推送状态,所以你正在寻找它处于推送状态但不是所有的故障,所以你必须决定我强制进入正常状态还是我有按住功能,如果有,那么你如何定义/采样...
标签: c++ embedded stm32 microcontroller mbed