Прерывания на любых ногах Ардуино

s.kurbatov
Offline
Зарегистрирован: 15.01.2019

Добрый вечер, господа! Образовалась у меня следующая проблема.....
Не могу заставить прерываться Ардуину нано при изменении состояния на 8 ноге (D8).
Да, в общем то, на любой, кроме 2 и 3, с которыми всё ясно)).
Вот маленькая тестовая программка. Из терминала видно, что рвётся только по переднему фронту.
А надо - по обоим, т.е. по изменению состояния на ноге.

const int pini = 8;
volatile unsigned long  tim, timo, del;
boolean  _out;

void setup()
{   Serial.begin(115200);
    pinMode (pini,OUTPUT);
    PORTB  = 0b00000001;
    PCICR  = 0b00000001;
    digitalWrite(pini, LOW);
    PCMSK0 = 0b00000001;
}
/// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ISR(PCINT0_vect) {
    if (!(PINB & (1 << PB0))) {
      tim = micros();
      del = tim - timo;
      timo = tim;
      Serial.print(" t ");
      Serial.print(tim);
      Serial.print(" d ");
      Serial.println(del);
   }
}    
/// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void loop() {
    digitalWrite(pini, _out);
   _out ^= 1;
    delay(500);
}

Терминал:

 t 1000044 d 1000044
 t 2000808 d 1000764
 t 3001580 d 1000772
 t 4002348 d 1000768
 t 5003112 d 1000764
 t 6003880 d 1000768
 t 7004644 d 1000764
 t 8005416 d 1000772
 t 9006180 d 1000764
 . . . . . . . . . . .
   Или это не возможно?...

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ознакомтесь пожалуйста с - http://arduino.ru/forum/obshchii/pesochnitsa-dlya-vsekh-novichkov#comment-406075

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Проблема надумана (от больших знаний), но давайте Вы сначала нормально вставите код, а там поговорим.

s.kurbatov
Offline
Зарегистрирован: 15.01.2019

Я очень извиняюсь......

const int pini = 8;
volatile unsigned long  tim, timo, del;
boolean  _out;

void setup()
{   Serial.begin(115200);
    pinMode (pini,OUTPUT);
    PORTB  = 0b00000001;
    PCICR  = 0b00000001;
    digitalWrite(pini, LOW);
    PCMSK0 = 0b00000001;
}

ISR(PCINT0_vect) {
    if (!(PINB & (1 << PB0))) {
      tim = micros();
      del = tim - timo;
      timo = tim;
      Serial.print(" t ");
      Serial.print(tim);
      Serial.print(" d ");
      Serial.println(del);
   }
}    

void loop() {
    digitalWrite(pini, _out);
   _out ^= 1;
    delay(500);
}

 

s.kurbatov
Offline
Зарегистрирован: 15.01.2019

Единственное, что приходит на ум (от недостатка знаний) - это проверять в прерывании, по какому фронту мы сюда попали и менять там же битик ICES1, разрешая прерывания по другому фронту. Но это, что называется, через одно место.... корявенько))

 volatile unsigned long  tim, timo, del;
boolean  _out, _in;

void setup()
{ Serial.begin(115200);
  pinMode (pini,OUTPUT);  

  TIMSK1 = (1<<ICIE1);
  TCCR1B = (1<<ICNC1) | (1<<ICES1);  
}
ISR (TIMER1_CAPT_vect) {
    tim = micros();
    del = tim - timo;
    timo = tim;
 
   _in = digitalRead(pini);
    if (_in == HIGH)  TCCR1B = 0;
    else              TCCR1B = (1<<ICES1);
   Serial.print(" t ");
   Serial.print(tim);
   Serial.print(" d ");
   Serial.println(del);
}

void loop() {
    digitalWrite(pini, _out);
   _out ^= 1;
    delay(500);
}

s.kurbatov
Offline
Зарегистрирован: 15.01.2019

Не менее коряво по смыслу, но намного изящнее по содержанию))

ISR (TIMER1_CAPT_vect) { 
    tim = micros();
    del = tim - timo;
    timo = tim;
  // ----------------------
    TCCR1B  ^=  (1<<ICES1);  
  // ----------------------
   Serial.print(" t ");
   Serial.print(tim);
   Serial.print(" d ");
   Serial.println(del);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я сократил Ваш пример, убрав всё лишее и выбросил вывод в сериал из обработчика прерывания. Вместо этого, я по прерыванию длблирую восьмой пин на 13-ый. Всё отлично мигает 13-м пином, только что протестировал.

static const uint8_t pini = 8;

void setup(void) {
	pinMode(pini, OUTPUT);
	pinMode(LED_BUILTIN, OUTPUT);
	PCICR  = bit(PCIE0);
	PCMSK0 = bit(PCINT0);
}

ISR(PCINT0_vect) {
	digitalWrite(LED_BUILTIN, digitalRead(pini));
}    

void loop(void) {
	static bool  _out = LOW;
	digitalWrite(pini, _out = !_out);
	delay(500);
}

 

s.kurbatov
Offline
Зарегистрирован: 15.01.2019

Все верно. Что то я не вникая в смысл вставил совершенно ненужную конструкцию if (!(PINB & (1 << PB0 {   и попытался изобрести велосипед)))

Спасибо большое!

RG22EM
Offline
Зарегистрирован: 27.08.2016

ЕвгенийП пишет:

Я сократил Ваш пример, убрав всё лишее и выбросил вывод в сериал из обработчика прерывания. Вместо этого, я по прерыванию длблирую восьмой пин на 13-ый. Всё отлично мигает 13-м пином, только что протестировал.

static const uint8_t pini = 8;

void setup(void) {
	pinMode(pini, OUTPUT);
	pinMode(LED_BUILTIN, OUTPUT);
	PCICR  = bit(PCIE0);
	PCMSK0 = bit(PCINT0);
}

ISR(PCINT0_vect) {
	digitalWrite(LED_BUILTIN, digitalRead(pini));
}    

void loop(void) {
	static bool  _out = LOW;
	digitalWrite(pini, _out = !_out);
	delay(500);
}

 

А где прочитать про загадочные строки 6 и 7?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

RG22EM пишет:

А где прочитать про загадочные строки 6 и 7?

http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A...