• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Сброс флага прерывания ESP8266

ptihka

New member
Всем привет! Подскажите пожалуйста как сбросить флаг прерывания ESP в ардуино. Есть команды из даташит на ESP8266 , но они мне всегда возвращают "НОЛЬ" не зависимо какие прерывания включены или какие флаги подняты, может я что то делаю не так , или есть какието другие варианты?
uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_W1TC_ADDRESS);
Serial.print ("gpio_status -");
Serial.println (gpio_status);
 

aZholtikov

Active member
Всем привет! Подскажите пожалуйста как сбросить флаг прерывания ESP в ардуино.
Если я правильно помню, то последовательность такая:

ETS_GPIO_INTR_DISABLE();
uint32_t gpioStatus = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpioStatus);
ETS_GPIO_INTR_ENABLE();
 

aZholtikov

Active member
В дополнение.

 

ptihka

New member
не помогает , выполнении команды , так же "gpioStatus = 0" это первое , а второе я так понимаю Вы скинули пример не со среды ARDUINO , это наверно эклипс , я с ним не работал , надо попробовать разобраться , может там работать будет , но хотелось бы и в ардуино разобраться.
ETS_GPIO_INTR_DISABLE(); ----- это я как понял отключение прерывания , оно не должно повлиять на чтение регистра состояния , или я не прав?
uint32_t gpioStatus = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
ETS_GPIO_INTR_ENABLE();
 

aZholtikov

Active member
не помогает , выполнении команды , так же "gpioStatus = 0" это первое , а второе я так понимаю Вы скинули пример не со среды ARDUINO , это наверно эклипс , я с ним не работал , надо попробовать разобраться , может там работать будет , но хотелось бы и в ардуино разобраться.
ETS_GPIO_INTR_DISABLE(); ----- это я как понял отключение прерывания , оно не должно повлиять на чтение регистра состояния , или я не прав?
uint32_t gpioStatus = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
ETS_GPIO_INTR_ENABLE();
Да. Это не Ардуино. Это "голый" SDK Espressif.
Вы сами дали такой пример. Я ответил.
Нужно Ардуино - используйте функции Ардуино. Типа attachInterrupt(interrupt, function, mode) и тд... https://esp8266-arduinoide.ru/prog/
 

ptihka

New member
Так проблемма в том что я в ардуино не могу считать регистр прерывания, именно считать регист и соответственно обнулить его , в этом и суть вопроса , а пример кода это то как я пробовал считать , и оно не получается , вот и задал вопрос про чтение регистров в ардуино среде.
 

aZholtikov

Active member
Можно увидеть полный код обработчика прерывания, в котором осуществляется попытка чтения регистра?
 

ptihka

New member
Конечно можно.

Код:
#include <Wire.h>
#include <SparkFun_APDS9960.h>

#define LED_1 D0   // пин выхода 1
#define LED_2 D6   // пин выхода 2
#define INT_a D2   // пин преывания

SparkFun_APDS9960 apds = SparkFun_APDS9960();
uint8_t PROX_INT_HIGH = 200;  // верхний предел для прерывания датчика
uint8_t PROX_INT_LOW  = 100;  // нижний предел для прерывания датчика
int a = 0;
//uint32_t gpio_status=0;

uint8_t proximity_data = 0;   // переменная данных датчика

volatile int flag_int = 0;    // флаг прерывания

void setup() {
  Wire.begin(D5, D7);         // назначение ножек I2C
  Serial.begin(9600);         // скорость порта UART
  attachInterrupt(INT_a, myIsr, FALLING);  // функыия прерывания

  apds.init() ;               //иниыиализация датчика

  apds.setProximityIntLowThreshold(PROX_INT_LOW);   //установка предела сробатывания прерывания для датчика
  apds.setProximityIntHighThreshold(PROX_INT_HIGH);

    apds.enableProximitySensor(true);               // включение режима датчика для считывания преблеждения с включенным прерыванием

    apds.setProximityGain(PGAIN_2X);                // установка режимов чуствительности датчиков
    apds.setLEDDrive(3);

    pinMode(LED_1, OUTPUT);          //настройка портов для светодиодов
    digitalWrite(LED_1, 0);

    pinMode(LED_2, OUTPUT);
    digitalWrite(LED_2, 0);

}

void loop() {
     //ETS_GPIO_INTR_DISABLE();
  uint32 gpio_status = GPIO_REG_READ(GPIO_OUT_W1TC_ADDRESS);
     //gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
     //gpio_status = GPIO_REG_READ(GPIO_STATUS_W1TC_ADDRESS);
  Serial.print ("gpio_status - ");
  Serial.println (gpio_status);
      //ETS_GPIO_INTR_ENABLE();

if (flag_int == 1){ 
  //detachInterrupt(INT_a);
  apds.readProximity(proximity_data);
  Serial.println(proximity_data);
   flag_int = 0;
  apds.clearProximityInt(); 
//attachInterrupt(INT_a, myIsr, FALLING);
 
}
  delay(250);
 
}

IRAM_ATTR void myIsr() { 
 
  flag_int = 1;
  if (a == 0 ){
    digitalWrite(LED_2, a);
    a++;
  }
    else    {
  digitalWrite(LED_2, a);
  a=0;
    }
}
 

aZholtikov

Active member
Зачем пытаться прочитать статус регистра если прерывание всего одно? Тем более +100500 раз в секунду в loop?
P.S. Ардуиновская attachInterrupt сама очищает регистр при возникновении прерывания. Вот и 0 всегда.
P.S.S. Не мешайте Ардуино и родное SDK. Или-или.
 

ptihka

New member
Это не тот код который мне нужен , это проверочный , дело в том что "gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);" которая должно выводить какой порт включен на прерывание выводит тоже ноль , не зависимо сколько и какие прерывания включены.
P.S. Ардуиновская attachInterrupt сама очищает регистр при возникновении прерывания. Вот и 0 всегда.
она очищает не в тот момент который мне нужен , она очищает после своего выполнения , а мне нужно чтобы я флаг очистил и прерывания не вполнилось. перед включение прерывания, после его отключения.
P.S.S. Не мешайте Ардуино и родное SDK. Или-или.
да я бы не против , знал бы как обратится к регистрам при помощи ардуино , в чем и суть.
Опишу в кратце что мне нужно , может в этом подскажите. Есть датчик APDS-9960 и всего две ноги D5 & D7 || SDA & SCL соответственно , я хочу чтобы на ноге D5 висело еще и прерывание от это го же датчика.
Мои действия : отключаю прерывания , инициализирую датчик , включаю прерывания , жду пока прийдет прерывания от APDS-9960 , отключаю прерывания , обрабатываю данные по I2C , включаю прерывания и жду его от датчика и так по кругу . Загвоздка в том что после отключения прерывания и обработки I2C прерывания опять срабатывает , я так понимаю что флаг прерывания в регистре поднят и мне его нужно обнулить.
 

aZholtikov

Active member
Есть датчик APDS-9960 и всего две ноги D5 & D7 || SDA & SCL соответственно , я хочу чтобы на ноге D5 висело еще и прерывание от это го же датчика.
Боюсь это невозможно... ;-(
P.S. Что за модуль ESP с таким маленьким количеством свободных "ног"?
 

ptihka

New member
Боюсь это невозможно... ;-(
с чем это связанно?
P.S. Что за модуль ESP с таким маленьким количеством свободных "ног"?
модуль тут совсем не причем . это все строение платы , модуль esp-12s , ног то занятых совсем нет кроме SDA & SCl , но нет возможность подвести других проводов к датчику.
 

ptihka

New member
Ну в Баском у меня бы получилось , но там нет поддержки ESP , я думаю и здесь должно работать , просто я с С-языком почти не знаком , а с ардуино знаком еще меньше .
Но обстоятельства заставляют изучат и то и другое :)
 

ptihka

New member
Не ужели никто не знает как прочитать или записать непосредственно регистры ESP8266 в Arduino IDE?
 

aZholtikov

Active member
Офф документация Espressif:

7.1.6. GPIO Interrupt Handler
Follow the steps below to clear interrupt status in GPIO interrupt processing function:

uint32 gpio_status;
gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
//clear interrupt status
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);

Больше ничего нет. Это и чтение и обнуление. И в Arduino IDE тоже.

P.S. Следим "за руками", а точнее за названием параграфа - Interrupt Handler. Это как бы намекает на то, что данные манипуляции можно (и нужно) производить ТОЛЬКО в обработчике прерывания.
 

ptihka

New member
Ну это понятно , в моем первом сообщении я так и писал теже самые команды , так делао в том что я не могу прочитать не один регистр , и даже регистр в котором указанно какие прерывания обработать а тоесть (GPIO_STATUS_ADDRESS ) , aZholtikov сами попробуйте считать хоть какой нибудь регистр , может у Вас получится. Может я что делаю не так.
 

aZholtikov

Active member
Код:
#include "Arduino.h"
#include "gpio.h"

volatile static uint32_t register_status = 0;
volatile static bool interrupt_flag = false;

void button_interrupt();

void setup()
{
  Serial.begin(115200);

  ETS_GPIO_INTR_DISABLE();
  ETS_GPIO_INTR_ATTACH(button_interrupt, NULL);
  gpio_pin_intr_state_set(GPIO_ID_PIN(5), GPIO_PIN_INTR_POSEDGE);
  gpio_pin_intr_state_set(GPIO_ID_PIN(6), GPIO_PIN_INTR_POSEDGE);
  gpio_pin_intr_state_set(GPIO_ID_PIN(7), GPIO_PIN_INTR_POSEDGE);
  ETS_GPIO_INTR_ENABLE();
}

void loop()
{
  if (interrupt_flag == true)
  {
    Serial.print("GPIO Register: ");
    Serial.println(register_status, BIN);
    interrupt_flag = false;
    delay(500); // Just for minimise printing frequency.
    ETS_GPIO_INTR_ENABLE();
  }
}

void IRAM_ATTR button_interrupt()
{
  if (interrupt_flag == false)
  {
    ETS_GPIO_INTR_DISABLE();
    uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
    register_status = gpio_status;
    GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
    interrupt_flag = true;
  }
}
 

ptihka

New member
Спасибо за пример , вроде что то работает , но я не могу понять логики . почему эта строка uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); начинает работа только после прерывания я так понимаю это регистр в котором сказано какой порт включен для прерывания , а значит он должен читаться в любой момент , или я опять не так что то думаю?
 

aZholtikov

Active member
Буду краток. Не правильно понимаете.

Это регистр флагов. Наличие установленного бита на определенной позиции только показывает какая «ножка» вызвала прерывание. И его надо сразу обнулять для продолжения работы прерываний. Фсё.

Все регистры очень подробно описаны в ESP8266 Technical Reference.
 
Сверху Снизу