我尝试附加一个类函数作为 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 的相对易用性)。
从
IRAM_ATTR
我假设您正在使用 ESP8266。 Arduino ESP8266 核心有一个 attachInterrupt()
重载,它接受 std::function
,它可以由来自 object和 member function 的
std::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;
}