Поделитесь службой прерывания между классом

Я хотел бы поделиться процедурой прерывания между классом. Я следовал этому руководству.

Но мне нужно вызвать функцию-член в функции обратного вызова, у меня проблема:

Это мой код:

Таймер.ч

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().

Как я могу вызвать нестатическую функцию-член? Или другое решение?

, 👍-1

Обсуждение

Ни один из этих результатов не помогает вам? https://arduino.stackexchange.com/search?q=invalid+use+non+static+member, @Majenko

нет, решение со статическим членом, @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