Счетчик на прерываниях

Igoreck
Offline
Зарегистрирован: 01.03.2017

Здравствуйте. 

Есть проблема не могу понять, -почему после остановки прерывания и в последующем возобновлении, прибавляет один инкремент. Это проявляется как на паузе, так и на сбросе. Может кто подскажет.

 

#include "button_key.h"
#include "SevSegShift.h"

#define interruptPin 2
#define START 1
#define RESET 10

#define SHIFT_PIN_SHCP 6
#define SHIFT_PIN_STCP 5
#define SHIFT_PIN_DS   4
SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP, 1, true);
//********************************************************************************

btn Btn5;//создадим обьекты кнопок "RESET"
btn Btn6;//создадим обьекты кнопок "START"

int distance;
bool flagStart;
volatile int counter ;  // переменная-счётчик 

void setup() {
  //Serial.begin(9600);
  byte numDigits = 4;
  byte digitPins[] = {A3, A2, A1, A0};
  byte segmentPins[] = {0, 1, 2, 3, 4, 5, 6, 7};//a,b,c,d,e,f,g,dp
  bool resistorsOnSegments = true; // «false» означает, что резисторы находятся на цифровых контактах.
  byte hardwareConfig = N_TRANSISTORS; // См. README.md для вариантов
  bool updateWithDelays = false; // Рекомендуется значение по умолчанию «false».
  bool leadingZeros = false; // Используйте «true», если вы хотите сохранить ведущие нули
  bool disableDecPoint = false; // Используйте «true», если ваша десятичная точка не существует или не связана
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
               updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(200);
  //+++++++++++++++++++++++++++++++++++++++++++
  pinMode(RESET, INPUT_PULLUP);
  pinMode(START, INPUT_PULLUP);

  pinMode(interruptPin, INPUT_PULLUP);
  //EICRA &= ~(1 << ISC00); //Сбрасываем ISC00
  EICRA = (1 << ISC01); // Устанавливаем ISC01 - отслеживаем FALLING на INT0
}
ISR(INT0_vect) {
  //if (millis() - last_time >= 10 ) {
  counter++;  //счетчик
  //    last_time = millis();enc =
  //  }
}
void loop() {
  int BtnReset = Btn5.key(RESET); //опрос кнопки ресет
  int BtnStart = Btn6.key(START); //опрос кнопки старт

  if (BtnStart == SHORT && flagStart == false) { //Старт
    EIMSK = (1 << INT0); // разрешаем прерывания
    flagStart = true; // поднимаем флаг
  }
  else if (BtnStart == SHORT && flagStart == true) { //Пауза
    EIMSK = (0 << INT0); // запрещаем прерывания
    flagStart = false; // сбрасываем флаг
  }
  if (BtnReset == SHORT) { //сброс
    EIMSK = (0 << INT0); // запрещаем прерывания
    distance = 0; // обнуляем переменную
    counter = 0; // обнуляем счетчик
    flagStart = false; // сбрасываем флаг
  }
  else if (flagStart == true) {// иначе если поднят флаг
    distance = counter; // из счетчика отправить достигнутом  
  }
  sevseg.setNumberF(distance); // вывод "достигнутое"
  sevseg.refreshDisplay();
}

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Может дребезг контактов плохо обрабатывается? Сэмулируй кнопку.

Igoreck
Offline
Зарегистрирован: 01.03.2017

BOOM пишет:

Может дребезг контактов плохо обрабатывается? Сэмулируй кнопку.

Да нет. Суть в чем. Когда например в режиме "Пауза", а индуктивный датчик не работает, то и нет приращения этой единицы.

А если в режиме "Пауза" или "Сброс", и при этом работает датчик, то только накинет единицу не более!

Тоесть проблема не в дребезге, там индуктивный датчик через оптрон!

nik182
Offline
Зарегистрирован: 04.05.2015

Перед разрешением прерываний надо сбрасывать флаг прерывания.

Igoreck
Offline
Зарегистрирован: 01.03.2017

nik182 пишет:

Перед разрешением прерываний надо сбрасывать флаг прерывания.

Да все четко.

EIFR = bit (INTF0);

Всем спасибо, и мира нам.