Поделитесь службой прерывания между классом
Я хотел бы поделиться процедурой прерывания между классом. Я следовал этому руководству.
Но мне нужно вызвать функцию-член в функции обратного вызова, у меня проблема:
Это мой код:
Таймер.ч
static void (*__handleISR)(void);
class Timer
{
public:
Timer();
~Timer();
static void init();
static void handleISR(void (*function)(void));
};
Таймер.cpp
Timer::Timer()
{
}
Timer::~Timer()
{}
void Timer::init()
{
TCCR2A = 0; //дефолт
TIMSK2 = 0b00000001; // ТОИЕ2
}
ISR (TIMER2_OVF_vect)
{
// 256-6=250 --> (250 х 16 мкс = 4 мс)
// Перезарядка таймера для того, чтобы остановить прерывание, если оно снизится в течение 4 мс
TCNT2 = 6;
__handleISR();
}
Device.h
class Device
{
public:
Device();
private:
void isr();
};
Device.cpp
Device::Device()
{
Timer::init();
Timer::handleISR(isr);
}
void Device::isr()
{
// Делать мои вещи
}
Если я устанавливаю функцию isr() статической, она работает. Но мне нужно вызвать члена с устройства в isr().
Как я могу вызвать нестатическую функцию-член? Или другое решение?
@oAGAo, 👍-1
Обсуждение1 ответ
Лучший ответ:
Это не конкретный вопрос Arduino, а вопрос C++, и поэтому вы можете получить больше или лучшие ответы на StackOverflow. В любом случае, я предложу возможное решение.
Метод-член всегда получает указатель на свой объект в виде скрытого первого аргумента, известного как this
. Только через этот аргумент такой метод может получить доступ к атрибутам члена или методам члена.
Метод класса не имеет этого параметра.
Тип функции, который вы определяете, совместим только с функциями или методами класса.
Поэтому вам необходимо предоставить указатель (или ссылку) на объект Device
.
Я сократил ваш пример и заменил макрос прерывания чем-то, что принимает стандартный компилятор C++, так как это не является частью проблемы.
Таймер.ч
#ifndef TIMER_H
#define TIMER_H
#include "Device.h"
class Timer
{
public:
static void setCallback(void (*function)(Device*), Device*);
};
#endif
Таймер.cpp
#include "Timer.h"
#define ISR(f) void f()
static void (*_function)(Device*);
static Device* _device;
void Timer::setCallback(void (*function)(Device*), Device* device)
{
_function = function;
_device = device;
}
ISR(TIMER2_OVF_vect)
{
_function(_device);
}
Device.h
#ifndef DEVICE_H
#define DEVICE_H
class Device
{
public:
Device();
private:
static void isr(Device* device);
void isr();
};
#endif
Device.cpp
#include "Device.h"
#include "Timer.h"
Device::Device()
{
Timer::setCallback(isr, this);
}
void Device::isr(Device* device)
{
device->isr();
}
void Device::isr()
{
// Делать мои вещи
}
Если вам не нужен объект Device
, вам не нужен метод-член. Затем используйте метод класса, как вы уже выяснили.
работает, спасибо большое :), @oAGAo
- Как получить переменную из функции обратного вызова?
- Чтение квадратурного энкодера в реальном времени с полным разрешением только с одним прерыванием на ATmega328
- Недопустимое использование выражения void (как использовать указатель функции с вводом)
- Проблема прерываний с датчиком потока
- Значение понижающего резистора для прерываний
- Прерывания таймера Arduino для PID
- Правильное использование SPI с ISR
- Контакты внешнего прерывания на наноклонах
Ни один из этих результатов не помогает вам? https://arduino.stackexchange.com/search?q=invalid+use+non+static+member, @Majenko
нет, решение со статическим членом, @oAGAo