如何附加类函数作为 ISR 回调

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

我尝试附加一个类函数作为 ISR 回调,但收到此错误:

lib/classA/classA.cpp: In member function 'uint8_t MethodA::Init()':
lib/classA/classA.cpp:32:71: error: invalid use of non-static member function 'void MethodA::FlowCounter()'
   attachInterrupt( digitalPinToInterrupt(PIN_B), FlowCounter, FALLING );
                                                                       ^
lib/classA/classA.cpp:12:16: note: declared here
 void IRAM_ATTR MethodA::FlowCounter() {
                ^~~~~~~
*** [.pio\build\featheresp32\lib71a\classA\classA.cpp.o] Error 1

如何在

FlowCounter
调用中正确引用
attachInterrupt
函数?

这是main.cpp文件:

#include <Arduino.h>
#include "classA.h"

MethodA myMethod( 5, 6 );

void setup() {
  myMethod.Init(); 
}

void loop() {
}

这是classA.h文件:

#pragma once

#include <Arduino.h>

class MethodA {

  public:

    MethodA( uint8_t _PIN_A, uint8_t _PIN_B );

    uint32_t stopCount;
    static const uint32_t stepCount;

    uint8_t Init();
    void Update();
    void StartCycle();
    
  private:

    volatile uint32_t flowCount;
    uint8_t pumpDone;

    void IRAM_ATTR FlowCounter();
    uint8_t PIN_A;
    uint8_t PIN_B;
 
};

还有classA.cpp文件:

#include <Arduino.h>

#include "classA.h"

const uint32_t MethodA::stepCount = 10;

MethodA::MethodA( uint8_t _PIN_A, uint8_t _PIN_B ) {
    PIN_A = _PIN_A;
    PIN_B = _PIN_B;
}

void IRAM_ATTR MethodA::FlowCounter() {

    flowCount++;

    if ( flowCount >= stopCount ) {
        digitalWrite( PIN_A, LOW );
        pumpDone = true;
    }

    return;
}

uint8_t MethodA::Init() {
  
  pinMode( PIN_A, OUTPUT );
  
  digitalWrite( PIN_B, LOW );

  pinMode( PIN_B, INPUT_PULLUP );
  
  attachInterrupt( digitalPinToInterrupt(PIN_B), FlowCounter, FALLING );

  return true;
}

void MethodA::Update() {

    if ( pumpDone ) {
        Serial.print( "Cycle complete.");
    }

    return;
}

void MethodA::StartCycle() {

    stopCount = flowCount + stepCount;
    digitalWrite( PIN_A, HIGH );
    pumpDone = false;
    return;
}

我尝试通过

static void IRAM_ATTR FlowCounter();
将 ISR 函数设为静态,但这让编译器对函数内的变量尖叫。 我尝试通过
MethodA::FlowCounter
引用它,但这产生了相同的错误。 我尝试使用指针
&FlowCounter
&Method::FlowCounter
无济于事。 所以我错过了一些有关 cpp 编程的基本知识(我更熟悉 Python 的相对易用性)。

c++ function pass-by-reference interrupt
1个回答
1
投票

IRAM_ATTR
我假设您正在使用 ESP8266。 Arduino ESP8266 核心有一个
attachInterrupt()
重载,它接受
std::function
,它可以由来自
object
member functionstd::bind() 生成。您正在调用错误的重载,该重载仅适用于指向静态函数的函数指针。

所以你只需更改它即可使用它:

uint8_t MethodA::Init() {
  pinMode( PIN_A, OUTPUT );
  digitalWrite( PIN_B, LOW );
  pinMode( PIN_B, INPUT_PULLUP );
  attachInterrupt(
    digitalPinToInterrupt(PIN_B),
    std::bind(&MethodA::FlowCounter, this),
    FALLING);
  return true;
}
© www.soinside.com 2019 - 2024. All rights reserved.