C++ Arduino如何计算对象数组中的外部中断? 问题

C++ Arduino如何计算对象数组中的外部中断? 问题,c++,arduino,interrupt-handling,esp32,C++,Arduino,Interrupt Handling,Esp32,我开始玩Arduino IoT(ESP32)。我从SD卡上的文件中读取GPIO配置。我有一个外部中断的问题。我需要计算给定GPIO上的中断数 我编写了一个存储GPIO配置的类,并将该类的对象放在一个全局数组中。如何计算给定管脚上的中断,以便使用适当的对象方法获得结果 我尝试了不同的解决方案,但问题在于ISR方法,它必须是静态的。此方法无法访问对象字段,因此我不知道在何处以及如何增加中断计数器 我把代码分成几个文件。我只附上解决这个问题所需的资料 这阻碍了我的计划。请帮忙 主文件: #define

我开始玩Arduino IoT(ESP32)。我从SD卡上的文件中读取GPIO配置。我有一个外部中断的问题。我需要计算给定GPIO上的中断数

我编写了一个存储GPIO配置的类,并将该类的对象放在一个全局数组中。如何计算给定管脚上的中断,以便使用适当的对象方法获得结果

我尝试了不同的解决方案,但问题在于ISR方法,它必须是静态的。此方法无法访问对象字段,因此我不知道在何处以及如何增加中断计数器

我把代码分成几个文件。我只附上解决这个问题所需的资料

这阻碍了我的计划。请帮忙

主文件:

#define GPIO_CONFIG_FILE "cfg/gpio.txt"
#define WIFI_AP_CONFIG_FILE "cfg/ap.txt"
#define WIFI_STA_CONFIG_FILE "cfg/sta.txt"
#define AVAILABLE_GPIO_CNT 7
#define LED_BUILTIN_OLIMEX 33
#define BTN_BUILTIN_OLIMEX 34

#include "FS.h"
#include "SD_MMC.h"
#include "GPIO_CONFIG.h"

GPIO_CONFIG gpio[AVAILABLE_GPIO_CNT];
uint32_t gpio_int_cnt[AVAILABLE_GPIO_CNT] = {0};

void setup() {
  if (checkSdCard()) {
    setUpPinsFromFile(GPIO_CONFIG_FILE);
  }
}

void loop() {
}
GPIO_CONFIG.h

#ifndef GPIO_CONFIG_h
#define GPIO_CONFIG_h

#include "Arduino.h"
#define ID_LENGTH 7

class GPIO_CONFIG {
  public:
    GPIO_CONFIG();
    void setUp(const char * key);
    void printConfig();
    uint8_t number();
    uint8_t mode();
    uint16_t multiplier();
    bool inversion();
    char * id();
    static void isr();
    static uint32_t int_cnt();

  private:
    uint8_t gp_number;
    uint8_t gp_mode;
    uint16_t gp_multiplier;
    uint32_t gp_init_value;
    bool gp_inversion;
    char gp_id[ID_LENGTH];
    //    const uint8_t gp_mode_array[4] = {INPUT, OUTPUT, INPUT_PULLUP};
};
#endif
#define AVAILABLE_GPIO_CNT 7

class GPIO_CONFIG;
typedef /*static*/ void (*isr_ptr)();
extern isr_ptr isrptr[AVAILABLE_GPIO_CNT];
extern GPIO_CONFIG gpio[AVAILABLE_GPIO_CNT];

(...)

public:
  void setIndex(const uint8_t * i);
  uint8_t index();

(...)

private:
  uint8_t gp_index;
  uint32_t gp_cnt_value;
GPIO_CONFIG.cpp

#include "GPIO_CONFIG.h"
GPIO_CONFIG::GPIO_CONFIG() {
  gp_number = 0;
  gp_multiplier = 1;
  gp_inversion = false;
  gp_init_value = 0;
}

void GPIO_CONFIG::setUp(const char * key) {
  //nr|id|name|mode|multi|inv|init
  char cfg[sizeof(key)];
  for (uint8_t b = 0; b < sizeof(key); ++b) {
    cfg[b] = key[b];
  }

  //PIN_NUMBER
  char * tok = strtok(cfg, "|");
  gp_number = atoi(tok);

  //ID
  tok = strtok(NULL, "|");
  for (int b = 0; b < sizeof(tok); b++) {
    if (b < ID_LENGTH) {
      gp_id[b] = tok[b];
    } else {
      break;
    }
  }
  gp_id[ID_LENGTH - 1] = '\0';

  //NAME
  strtok(NULL, "|");

  //MODE
  tok = strtok(NULL, "|");
  gp_mode = atoi(tok);

  //MULTIPLIER
  tok = strtok(NULL, "|");
  gp_multiplier = atoi(tok);

  //INVERSION
  tok = strtok(NULL, "|");
  gp_inversion = (atoi(tok) > 0);

  //INITIAL VALUE
  tok = strtok(NULL, "|");
  gp_init_value = atoi(tok);

  //0-in; 1-out; 2-int
  if (gp_mode != 1) {
    if (gp_inversion) { //sterowanie podstawowe przez vcc
      pinMode(gp_number, INPUT_PULLUP);
    } else {
      pinMode(gp_number, INPUT);
    }
    if (gp_mode > 2) {
      attachInterrupt(digitalPinToInterrupt(gp_number), isr, FALLING);
    }
  } else {
    pinMode(gp_number, OUTPUT);
  }
}

void GPIO_CONFIG::printConfig() {
#ifdef DEBUG
  Serial.print("GPIO_CONFIG:");
  Serial.print(" -no:");
  Serial.print(gp_number);
  Serial.print(" -id:");
  Serial.print(gp_id);
  Serial.print(" -mode:");
  Serial.print(gp_mode);
  Serial.print(" -multi:");
  Serial.print(gp_multiplier);
  Serial.print(" -inv:");
  Serial.print(gp_inversion);
  Serial.println("");
#endif
}

uint8_t GPIO_CONFIG::number() {
  return gp_number;
}

uint8_t GPIO_CONFIG::mode() {
  return gp_mode;
}

uint16_t GPIO_CONFIG::multiplier() {
  return gp_multiplier;
}

bool GPIO_CONFIG::inversion() {
  return gp_inversion;
}

char * GPIO_CONFIG::id() {
  return gp_id;
}

void GPIO_CONFIG::isr() {
//  gpio_int_cnt[0]++;
}

uint32_t GPIO_CONFIG::int_cnt() {
//  return gpio_int_cnt[0];
}
void GPIO_CONFIG::setIndex(const uint8_t * i){
  gp_index = *i;
  isrptr[gp_index] = &isr;
}

uint8_t GPIO_CONFIG::index(){
  return gp_index;
}

void GPIO_CONFIG::setUp(const char * key) {
  (...)
  attachInterrupt(digitalPinToInterrupt(gp_number), isrptr[gp_index], FALLING);
  (...)
}

void GPIO_CONFIG::isr() {
  for(uint8_t i=0; i<AVAILABLE_GPIO_CNT; ++i){
    if(&isrptr[i] == &gpio[i].isr()){ //here is my actualy problem. how can i compare this?
      gpio[i].increment_cnt_value();
      break;
    }
  }
}

uint32_t GPIO_CONFIG::int_cnt() {
  return gp_cnt_value;
}
GPIO_CONFIG.h

#ifndef GPIO_CONFIG_h
#define GPIO_CONFIG_h

#include "Arduino.h"
#define ID_LENGTH 7

class GPIO_CONFIG {
  public:
    GPIO_CONFIG();
    void setUp(const char * key);
    void printConfig();
    uint8_t number();
    uint8_t mode();
    uint16_t multiplier();
    bool inversion();
    char * id();
    static void isr();
    static uint32_t int_cnt();

  private:
    uint8_t gp_number;
    uint8_t gp_mode;
    uint16_t gp_multiplier;
    uint32_t gp_init_value;
    bool gp_inversion;
    char gp_id[ID_LENGTH];
    //    const uint8_t gp_mode_array[4] = {INPUT, OUTPUT, INPUT_PULLUP};
};
#endif
#define AVAILABLE_GPIO_CNT 7

class GPIO_CONFIG;
typedef /*static*/ void (*isr_ptr)();
extern isr_ptr isrptr[AVAILABLE_GPIO_CNT];
extern GPIO_CONFIG gpio[AVAILABLE_GPIO_CNT];

(...)

public:
  void setIndex(const uint8_t * i);
  uint8_t index();

(...)

private:
  uint8_t gp_index;
  uint32_t gp_cnt_value;
GPIO_CONFIG.cpp

#include "GPIO_CONFIG.h"
GPIO_CONFIG::GPIO_CONFIG() {
  gp_number = 0;
  gp_multiplier = 1;
  gp_inversion = false;
  gp_init_value = 0;
}

void GPIO_CONFIG::setUp(const char * key) {
  //nr|id|name|mode|multi|inv|init
  char cfg[sizeof(key)];
  for (uint8_t b = 0; b < sizeof(key); ++b) {
    cfg[b] = key[b];
  }

  //PIN_NUMBER
  char * tok = strtok(cfg, "|");
  gp_number = atoi(tok);

  //ID
  tok = strtok(NULL, "|");
  for (int b = 0; b < sizeof(tok); b++) {
    if (b < ID_LENGTH) {
      gp_id[b] = tok[b];
    } else {
      break;
    }
  }
  gp_id[ID_LENGTH - 1] = '\0';

  //NAME
  strtok(NULL, "|");

  //MODE
  tok = strtok(NULL, "|");
  gp_mode = atoi(tok);

  //MULTIPLIER
  tok = strtok(NULL, "|");
  gp_multiplier = atoi(tok);

  //INVERSION
  tok = strtok(NULL, "|");
  gp_inversion = (atoi(tok) > 0);

  //INITIAL VALUE
  tok = strtok(NULL, "|");
  gp_init_value = atoi(tok);

  //0-in; 1-out; 2-int
  if (gp_mode != 1) {
    if (gp_inversion) { //sterowanie podstawowe przez vcc
      pinMode(gp_number, INPUT_PULLUP);
    } else {
      pinMode(gp_number, INPUT);
    }
    if (gp_mode > 2) {
      attachInterrupt(digitalPinToInterrupt(gp_number), isr, FALLING);
    }
  } else {
    pinMode(gp_number, OUTPUT);
  }
}

void GPIO_CONFIG::printConfig() {
#ifdef DEBUG
  Serial.print("GPIO_CONFIG:");
  Serial.print(" -no:");
  Serial.print(gp_number);
  Serial.print(" -id:");
  Serial.print(gp_id);
  Serial.print(" -mode:");
  Serial.print(gp_mode);
  Serial.print(" -multi:");
  Serial.print(gp_multiplier);
  Serial.print(" -inv:");
  Serial.print(gp_inversion);
  Serial.println("");
#endif
}

uint8_t GPIO_CONFIG::number() {
  return gp_number;
}

uint8_t GPIO_CONFIG::mode() {
  return gp_mode;
}

uint16_t GPIO_CONFIG::multiplier() {
  return gp_multiplier;
}

bool GPIO_CONFIG::inversion() {
  return gp_inversion;
}

char * GPIO_CONFIG::id() {
  return gp_id;
}

void GPIO_CONFIG::isr() {
//  gpio_int_cnt[0]++;
}

uint32_t GPIO_CONFIG::int_cnt() {
//  return gpio_int_cnt[0];
}
void GPIO_CONFIG::setIndex(const uint8_t * i){
  gp_index = *i;
  isrptr[gp_index] = &isr;
}

uint8_t GPIO_CONFIG::index(){
  return gp_index;
}

void GPIO_CONFIG::setUp(const char * key) {
  (...)
  attachInterrupt(digitalPinToInterrupt(gp_number), isrptr[gp_index], FALLING);
  (...)
}

void GPIO_CONFIG::isr() {
  for(uint8_t i=0; i<AVAILABLE_GPIO_CNT; ++i){
    if(&isrptr[i] == &gpio[i].isr()){ //here is my actualy problem. how can i compare this?
      gpio[i].increment_cnt_value();
      break;
    }
  }
}

uint32_t GPIO_CONFIG::int_cnt() {
  return gp_cnt_value;
}
void GPIO_CONFIG::setIndex(const uint8_t*i){
gp_指数=*i;
isrptr[gp_索引]=&isr;
}
uint8\u t GPIO\u配置::索引(){
返回gp_指数;
}
无效GPIO_配置::设置(常量字符*键){
(...)
附件中断(数字插针中断(gp\U编号),isrptr[gp\U索引],下降);
(...)
}
无效GPIO_配置::isr(){

对于(uint8_t i=0;i我已经查看了您的代码好几次,都找不到您的ISR。我知道如何在简单的C代码中处理这类问题:您只需为每个中断引脚定义一个包含一个元素的数组,并从其各自的ISR中递增该元素。我不知道如何将其与您所展示的内容联系起来

经常引起问题的部分是,您通常需要将主代码和ISR之间共享的变量定义为volatile。如果不这样做,可能会导致很难发现的问题,因为编译器会优化掉它认为没有更改的内容(在ISR或主代码中)


致以最诚挚的问候,

谢谢您的回复。我正在编辑我的提问。我有一些想法,但这会导致新问题。@EDIT 2018/01/04 08:10我添加了一些文件更改,但在GPIO_CONFIG.cpp上遇到问题。
if(&isrptr[I]=&GPIO[I].isr()){//这是我的实际问题。我如何比较这一点?
这是一个问答网站,而不是博客或论坛。如果你对你的问题有答案,就这样写并接受它(然后恢复上次编辑)。||