Внутренние прерывания

alexbmd
Offline
Зарегистрирован: 15.01.2016

ua6em на талкнули меня на мысль.. попробую отпишусь

Arhat109 да леонардо. но если можете попробовать на мега тоже хорошо я от неё и отталкивался..

Green а может все дело в  EIFR  да так и попробую...

alexbmd
Offline
Зарегистрирован: 15.01.2016

меня смущают эти две фразы

Therefore, it is recommended to first (before set the EICRA) disable INTn by clearing its Interrupt Enable bit in the EIMSK Register - получается мы до EICRA должны выполнить EIMSK |= 1; ?

When an INT[6;3:0] bit is written to one and the I-bit in the Status Register (SREG) is set (one) then interrupt is enabled. - получается SREG тоже надо заенаблить... а ну да это как раз sei(),reti()... получается они необходимы но они и так должны быть заенаблены поумолчанию, плюс у меня в коде это тоже было. значит этот пункт выполнен. остается непонятен первый выше

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Уже не сегодня...

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Леонардо с утра забрал с почты, вечер свободный (с 23), интересно, попробую 

alexbmd
Offline
Зарегистрирован: 15.01.2016

да хоть бы кто выложил рабочий код с 328 там дальше всё понятно...

[off]кое какие мысли есть после очередного внимательного прочтения шита[/off] 

пока удалось добиться нормального начального состояния и разового тригера. повторно не тригериться :/

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

я не смогу...

совет, посмотри файл WInterrupts.c где сидит attachInterrupt

b707
Offline
Зарегистрирован: 26.05.2017

по совету Green сделал последовательную замену ардуино-стайла на регистры. На атмеге328 у меня все работает

const int btPin  = 2;                   //int0!
const int ledPin = 13;
volatile bool flag;

void setup()
{
  DDRD &= ~(1<< 2); PORTD |= (1<<2); //pinMode(btPin, INPUT_PULLUP); 

  DDRB |= (1<<5);                    //pinMode(ledPin, OUTPUT);

  //attachInterrupt(digitalPinToInterrupt(btPin), pinChange, CHANGE);
  EIMSK &= ~(1 << INT0); //INT0 is disabled to avoid false interrupts when mainuplating EICRA
  EICRA |= (1 << ISC00); //External Interrupt Control Register A - configured to trigger on change
  EIFR &= ~(1 << INTF0); //External Interrupt Flag Register -here it is cleared
  EIMSK |= (1 << INT0); //Enable INT0
  sei(); //Enable global interrupts
}

void loop()
{
  if (flag) {
    digitalWrite(ledPin, !digitalRead(ledPin)); //инвертируем LED
    delay(500);
    flag = false;
  }
}

ISR(INT0_vect){

  flag = true;
}

alexbnd - а теперь сравните со своим кодом в сообщении #26. И обратите внимание, насколько "неряшливый" код у вас и насколько более читабельный здесь. Здесь нет прямого присвоения значений целым регистрам и не используются магические числа, кроме номеров пинов. И я убежден, что именно в этом - причина ваших неудач

b707
Offline
Зарегистрирован: 26.05.2017

alexbmd пишет:

меня смущают эти две фразы

Therefore, it is recommended to first (before set the EICRA) disable INTn by clearing its Interrupt Enable bit in the EIMSK Register - получается мы до EICRA должны выполнить EIMSK |= 1; ?

вы английский плохо понимаете? - написано - "disable INTn by clearing its Interrupt Enable bit".  Выключить путем сброса соответвующего бита! А вы вместо этого что делаете? - EIMSK |= 1; ? устанавливаете бит!

 

alexbmd
Offline
Зарегистрирован: 15.01.2016

тьфу блин просто удалилл reti и все сразу заработало. на простом колхозном, можете обьяснить что делал reti, точнее почему он блокировал повторное срабатывание?

@b707"А вы вместо этого что делаете? - EIMSK |= 1; " а вы тоже это делаете в 15 строчки :)

плюс у вас может получится trigger on RISING потому что вы не очистили регистр предварительно. или я не прав ?

плюс EIFR  в мануале написано надо выставить в 1 для сброса а не в ноль как делаете вы, или я не прав ?

 

[off]и сравнивайте с 39 сообщением ане29, там мой правильный вчерашний код, только reti сегодня удалил ;) спасибо[/off]

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

alexbmd пишет:

тьфу блин просто удалилл reti и все сразу заработало. на простом колхозном, можете обьяснить что делал reti, точнее почему он блокировал повторное срабатывание?

 

reti() возвращает из прерыравания и разрешает прерыравания. Но не восстанавливает ни SREG ни контекст. Надо смотреть ассемблерный код. Скорее всего при входе в прерывание в стек пихается SREG в результате если его оттуда не вынуть, то по reti программа улетит хз куда. Т.е. похоже, что оно не на прерывания переставало реагировать, а висло.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Пихается и не только SREG .. видмо стек таки плыл..

b707
Offline
Зарегистрирован: 26.05.2017

alexbmd пишет:

тьфу блин просто удалилл reti и все сразу заработало.

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

Цитата:
@b707"А вы вместо этого что делаете? - EIMSK |= 1; " а вы тоже это делаете в 15 строчки :)

Disable от Enable не отличаете? Сначала в 12 строке выключаем прерывание, потом настраиваем, потом включаем обратно в строке15

Цитата:
плюс у вас может получится trigger on RISING потому что вы не очистили регистр предварительно. или я не прав ?

вы правы, мог бы, если эта настройка была в середине программы, но в данном случае все работает и так. Хотя соглашусь. что это такой же гавнокод, как у вас на прошлой странице

Цитата:
плюс EIFR  в мануале написано надо выставить в 1 для сброса а не в ноль как делаете вы, или я не прав ?

да, возможно.

 

 

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Посомтрел из любопытства что делается в прерывании :


<__vector_1>:        
 push	r1           
 push	r0           
 in	r0, 0x3f
 push	r0           
 eor	r1, r1       
 push	r24          
 ldi	r24, 0x01
 sts	0x0126, r24  
 reti                
 pop	r24          
 pop	r0           
 out	0x3f, r0
 pop	r0           
 pop	r1           
 reti                


Прога выпрыгивает не восстановив рабочие регистры и не высвободив стек.

b707
Offline
Зарегистрирован: 26.05.2017

dimax пишет:

Посомтрел из любопытства что делается в прерывании :

Прога выпрыгивает не восстановив рабочие регистры и не высвободив стек.

 

dimax - это в случае лишнего reti() в конце, правильно я понимаю?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

думаю в 10 строке выпрыгивает ))) этого ассемблера не знаю, сильно не пинать

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

b707, лишний reti в середине ))  Это собссно был вот этот фрагмент:

ISR(INT0_vect){ //execute ISR when trigger
        flag = true;
        reti();
}

 

alexbmd
Offline
Зарегистрирован: 15.01.2016

Финал: даже мой код с самого первого поста прекрасно работал бы не засунь я туда reti()

а почему я засунул reti() ? читаем мануал - reti() Returns from an interrupt routine, enabling global interrupts. This should be the last command executed before leaving an ISR. и вот как понять их же мануал на их же камень бог их знает ? :/

b707 "вы английский плохо понимаете? - написано - "disable INTn by clearing" я конечно не шекспир, но отличить дизабл от енабл в состоянии. почему я на дизабл предположил EIMSK = 1 ? да потому что читаем опять мануал reset EIFR flag by clearing bit. и в даном случае как раз надо записать единицу. вас никогда ни что не вводило в заблуждение ? и вас сразу после этого отправляли учить blink или variables? ядуаю надо быть немного терпимее и вежливее к другдругу ;) но это IMHO

b707 "//INT0 is disabled to avoid false interrupts when mainuplating EICRA" осмелюсь утверждать что нет необходимости в отключение в 12 строке. а вот коентарий ложный. это вас не спасет если событие уже произошло.

b707 "что это такой же гавнокод" сейчас вы обидели весь коллектив arduino LLC :) по сути это просто репликация их примера https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ через регистры. 

asam пишут что всётаки enabling global interrupts но похоже что таки висло, хотя я не понимаю почему, мы же просто повторно активировали глобальные прерывания. если мы два раза запишем один и тот же бит ничего же страшного не происходит PORTB = b10000000; (2 раза).при чем тут перемещает указатель черти куда?

за наводку на reti всем спасибо! кто бы мог подумать :)

качая одной рукой ребенка а второй накалякал максимально правильный (даже для подстраховки избыточный) код + важна очередность регистров + коректный вход и выход = http://arduino.ru/forum/programmirovanie/vnutrennie-preryvaniya#comment-444802

есть коментарии/улучшения :) ?

 

PS: кстати это самая полная и детальная версия из всех виденных мной в нете. Даже у Гамонна такой нету :)

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

От многих знаний, много печали.

Вот если бы ТС вместо мудрёного reti() написал бы обычный рабоче-крестьянский return, компилятор бы отработал нормально и всё бы нормально восстанавливалось.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Arhat109-2 пишет:

reti() - точно не нужен, но конкретно в этом контексте мешать не должен. 

Это он тебе не должен. А так-то мешает. Наверное, компилятор кривой. Или язык.

alexbmd
Offline
Зарегистрирован: 15.01.2016

dimax пишет:

Прога выпрыгивает не восстановив рабочие регистры и не высвободив стек.

dimax  а почему же они в мануале пишут should be the last command executed before leaving an ISR ?

и если оно не нужно на самом деле, в какой гипотетической ситуации оно(reti) может пригодиться ? при этом чтоб всё коректно востановилось

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

ну, я же говорил "от многих знаний, много печали"

alexbmd пишет:

почему же они в мануале пишут should be the last command executed before leaving an ISR ?

Потому что это так и есть. Но Вы же пишете на С++, а на ассемблере. Компилятор вставит эту команду сам так, как ему нужно и там где ему нужно - не мешайте ему.

alexbmd пишет:

и если оно не нужно на самом деле, в какой гипотетической ситуации оно(reti) может пригодиться ?

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

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

alexbmd, Евгений уже ответил. Не понятно где вы вычитали про этот reti(), единственный случай, когда этот макрос может потребоваться -это при выполнении "голых" прерываний, но это обычным ардуинщикам никогда не пригодится, разве что  для самых пытливых и просветлённых :) Я за несколько лет всего один раз его использовал.

alexbmd
Offline
Зарегистрирован: 15.01.2016

dimax Евнений наконец я понял а то за бугром детальной информацией  особбо не разживешся спасибо!

dimax да много где упоминается даже в avr\interrupt.h :)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

alexbmd пишет:

качая одной рукой ребенка а второй накалякал максимально правильный (даже для подстраховки избыточный) код + важна очередность регистров + коректный вход и выход = http://arduino.ru/forum/programmirovanie/vnutrennie-preryvaniya#comment-444802есть коментарии/улучшения :) ?

Да по мелочам докапаться можно :)

EIFR  |= 1;   // clear flag INT0 for event fired before attachINT0

Например это, -так не стоит делать не убедившись, что там стоит единица. Ибо если её там нет, то вы этой командой её как раз установите.  Обычно пишут EIFR=EIFR; Что устранит все единицы, если они там были.

DDRC = 0xFF; //output for Led PC7

Конечно на микре всего два бита в порту "С" но что б не дёргать 6-й бит, лучше поднять только 7-й бит  DDRC|=1<<DDC7;

flag=0; flag = true;

Это конечно не ошибка, но лучше писать в каком-то одном стиле, либо текст либо цифры

sei();        // enable global interrupts by I:SREG

Функция setup() сама добавляет эту команду.

 

 

alexbmd
Offline
Зарегистрирован: 15.01.2016

dimax пишет:

EIFR |= 1; // clear flag INT0 for event fired before attachINT0

Например это, -так не стоит делать не убедившись, что там стоит единица. Ибо если её там нет, то вы этой командой её как раз установите.  

ну там мне и нужна как раз единица (кторая делает clear если я правильно понял мануал) не взирая на то что там было до неё,  разве не правильно ?

DDRC, flag, знаю но целью было прерывания остальное меня не волновало и стоит там лишь чтоб убедиться  что они работают а так конечно надо делать как вы говорите ;)

sei - я же говорю что даже избыточно :) для подстраховки. без этого тоже будет работать и без коректного выхода ISR

/ спасибо verifyed by dimax :)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

alexbmd, все флаговые регистры в AVR имеют такую особенность - значение ячейки инвертируется при записи в неё единицы. Поэтому если там был ноль - то будет единица, и как только прерывание будет разрешено -оно сразу выполниться, вне зависимости было физическое событие или нет. Поэтому нужно либо проверить что там, либо сделать как я написал выше.

alexbmd
Offline
Зарегистрирован: 15.01.2016

dimax пишет:

 значение ячейки инвертируется при записи в неё единицы. Поэтому если там был ноль - то будет единица

чтото я запутался :)

было               0         1
дабавили       |=1      |=1
стало              1         1

правильно я так и хочу, если было 0 стало 1. если было 1 стало 1.

1 = сбросить флаг прерывания. чтобы как только прерывание было разрешено оно НЕ сработало. т.к. нету флага. в случае данного регистра нету = 1. 

или я вас не понял ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

alexbmd, видимо нас не понял. Уж не знаю как ещё проще объяснить. У флаговых регистров AVR два основных принципа: - (1)он принимает только запись единицы, а на запись ноля не реагирует. (2) При записи в флаговый регистр единицы происходит инверсия содержимого.  0 + 1 = 1  и соответссно  1 + 1 =0

Green
Offline
Зарегистрирован: 01.10.2015

dimax, можно проще.) Чтобы сбросить флаг - нужно записать в него 1-цу. Это извращение АVR. Причём не обязательно читать-писать через |=, а именно =, т.к. запись 0 ни на что влияния не оказывает.

alexbmd
Offline
Зарегистрирован: 15.01.2016

dimax пишет:

 Поэтому нужно либо проверить что там

а как проверить что в EIFR? как его прочитать ? перерыл весь интернет , только - как записать.

Green
Offline
Зарегистрирован: 01.10.2015

alexbmd пишет:

а как проверить что в EIFR? как его прочитать ? перерыл весь интернет , только - как записать.


Да обычным образом, читаешь и всё.)

dimax, исключающее ИЛИ здесь не канает!) Установить флаг программно записью 1 НЕЛЬЗЯ! Т.е., если флаг был 0, а мы пытаемся записать туда 1, надеясь на то что после этого он станет в 1 - получаем ФИГ ВАМ! Поэтому я и говорю что у АVR нет программных прерываний.) Только аппаратные!( Хочется программно - можно, но для этого нужно установить требуемый уровень на требуемой ноге, в данном случае на INT0. А установить этот уровень можно и программно.) Но для этого нужно настроить ногу на выход и установить требуемый уровень на этом выходе.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Green, да про установку флага видимо фигню сморозил, в голове каша после stm32 :)

alexbmd
Offline
Зарегистрирован: 15.01.2016

ооо arm впереди...

Коллеги так как же прочитать EIFR?  "читаешь и всё" компилятор не распознаёт :(

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

alexbmd, выходит что читать его не нужно, если конечно не собираетесь обрабатывать события без прерывания. Можно сбросить превентивно. EIFR=(1/2/3) или EIFR= EIFR&(1/2/3)   Или EIFR=EIFR

Green
Offline
Зарегистрирован: 01.10.2015

alexbmd пишет:

ооо arm впереди...

Коллеги так как же прочитать EIFR?  "читаешь и всё" компилятор не распознаёт :(


Какой там ещё arm, если вы EIFR прочитать не можете!)
 

alexbmd
Offline
Зарегистрирован: 15.01.2016

вот dimax даже на asm его не может прочитать, или Green владеет скрижалью всевидящего ока ;)

зачем кичиться если можно просто подсказать менее сведущему коллеги? если конечно знаете.

 

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

alexbmd пишет:

ооо arm впереди...

Коллеги так как же прочитать EIFR?  "читаешь и всё" компилятор не распознаёт :(

 

А что, разве вот так не работает?

uint8_t data = EIFR;

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

alexbmd пишет:

или Green владеет скрижалью всевидящего ока ;)

Green владеет Ржавой Секирой Ужоса... 

Ну и программированием, маленько. 

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

asam пишет:

А что, разве вот так не работает?

У всех работает. А ТС читает каким-то никому неизвестным способом  "читаешь и всё", и у него компилятор ругается.

alexbmd пишет:

 "читаешь и всё" компилятор не распознаёт :(

alexbmd, Вы, пожалуйста, вместо стенаний типа

alexbmd пишет:

зачем кичиться если можно просто подсказать менее сведущему коллеги? если конечно знаете.

всегда публикуйте код! Ну откуда кому знать каким там "читаешь и всё" Вы его читали? Проблема настолько тривиальна, что никому непонятно, в чём она собственно состоит, и как Вы умудрились не прочитать. Этого действительно никто не понимает! Как, впрочем, никто не понимает, нафига Вам его читать, но это отдельный вопрос.

Публикуйте код и Вам всё подскажут.

И ещё

alexbmd пишет:

вот dimax даже на asm его не может прочитать

dimax что-то в этом контроллере не может прочитать? Давно так не смеялся. Вы бы поаккуратнее, а то все куры со смеху передохнут, из чего омлет делать-то будем? :)))

alexbmd
Offline
Зарегистрирован: 15.01.2016

шутил же я конечно. так что не помрут куры. пробовал напрямую выводить. чёто не выходило. затупил. сори. щя попробую через переменную.

попробовал - тоже самое.  точнее я её читал но там всегда нули вот я и подумал что неправильно как то читал. ан нет , как предложили выше тоже там всегда нули.  хотел увидеть там единицу. чёто не получается.

вот запихал везде где можно принт а единицу всеравно не вижу

#include <avr/interrupt.h>
volatile boolean flag = 0;
uint8_t data = EIFR;

//mega32u4
void setup()
{

  Serial.begin(115200);
  while (!Serial);
  delay(3000);
  DDRD = 0; PORTD = 1; //input PULL-UP and default state is ‘1’ for INT0 PD0
  DDRC = 0xFF; //output for Led PC7
  PORTC &= ~(1 << 7);
  Serial.println(data);
  //attachInterrupt()
  EIMSK &= ~1;  // detachINT0
  EICRA &= ~3;  // clear existing INT0 flags
  EICRA |= 1;   // 0:LOW,1:CHANGE,2:FALLING,3:RISING for INT0
  Serial.println(data);
  EIFR  = 1;   // clear flag INT0 for event fired before attachINT0
  Serial.println(data);
  EIMSK |= 1;   // attachINT0
  Serial.println(data);

}
void loop()
{ Serial.println(data);
  if (flag) {
    PORTC ^= (1 << 7); //инвертируем состояние пина
    flag = 0;
  }
  delay(2000);
  Serial.println(data);
}

ISR(INT0_vect) { //execute ISR when fired
  Serial.println(data);
  //EIMSK &= ~1;   // detachINT0 immediately after fired
  flag = 1;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

alexbmd пишет:

вот запихал везде где можно принт а единицу всеравно не вижу

#include <avr/interrupt.h>
volatile boolean flag = 0;
uint8_t data = EIFR;

//mega32u4
void setup()
{

  Serial.begin(115200);
  while (!Serial);
  delay(3000);
  DDRD = 0; PORTD = 1; //input PULL-UP and default state is ‘1’ for INT0 PD0
  DDRC = 0xFF; //output for Led PC7
  PORTC &= ~(1 << 7);
  Serial.println(data);
  //attachInterrupt()
  EIMSK &= ~1;  // detachINT0
  EICRA &= ~3;  // clear existing INT0 flags
  EICRA |= 1;   // 0:LOW,1:CHANGE,2:FALLING,3:RISING for INT0
  Serial.println(data);
  EIFR  = 1;   // clear flag INT0 for event fired before attachINT0
  Serial.println(data);
  EIMSK |= 1;   // attachINT0
  Serial.println(data);

}
void loop()
{ Serial.println(data);
  if (flag) {
    PORTC ^= (1 << 7); //инвертируем состояние пина
    flag = 0;
  }
  delay(2000);
  Serial.println(data);
}

ISR(INT0_vect) { //execute ISR when fired
  Serial.println(data);
  //EIMSK &= ~1;   // detachINT0 immediately after fired
  flag = 1;
}

 

Алекс, простите, вы идиот? Или это троллинг такой?

Вы СНАЧАЛА приравняли переменную data регистру, ПОТОМ в него записали единицу - и думаете в data сама собой тоже появится единица?????

какие там прерывания. когда вы просто программировать не умеете...

alexbmd
Offline
Зарегистрирован: 15.01.2016

b707 вы идиот ?или просо у вас воспитания нет? "образование может быть средним, а воспитание должно быть высшим"

да затупил, с кем не бывает, когда на код остается 5 минут в день, еще и не такое бывает. при этом остальное время тоже не game of trone или line age2 смотрю. но вас еще ни разу не оскорбил. или вы такой умный отродясь? я до этого напрямую выводил всеравно нули. попробую еще. 

b707
Offline
Зарегистрирован: 26.05.2017

alexbmd пишет:

 до этого напрямую выводил всеравно нули. попробую еще. 

попробуйте, если опять нули будут -приходите, будем разбираться.

Но так, как вы "попробовали" выше - ГАРАНТИРОВАНО работать не может, независмо от того, что читаете - "крутой" регистр или самую обычную переменную

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

alexbmd пишет:

b707 вы идиот ?или просо у вас воспитания нет? "образование может быть средним, а воспитание должно быть высшим"

Так! Это чо за херня?

Ты пришел с просьбой об объяснениях и помощи. Тем самым ты согласился быть в положении ниже знающих. Следовательно готов терпеть глум и унижения, ради знаний.

Не готов? Пи..дуй нахер в гугль, учиться самостоятельно.

#include <avr/interrupt.h>
volatile boolean flag = 0;
uint8_t * data = &( EIFR);

//mega32u4
void setup()
{

  Serial.begin(115200);
  while (!Serial);
  delay(3000);
  DDRD = 0; PORTD = 1; //input PULL-UP and default state is ‘1’ for INT0 PD0
  DDRC = 0xFF; //output for Led PC7
  PORTC &= ~(1 << 7);
  Serial.println(*data);
  //attachInterrupt()
  EIMSK &= ~1;  // detachINT0
  EICRA &= ~3;  // clear existing INT0 flags
  EICRA |= 1;   // 0:LOW,1:CHANGE,2:FALLING,3:RISING for INT0
  Serial.println(*data);
  EIFR  = 1;   // clear flag INT0 for event fired before attachINT0
  Serial.println(*data);
  EIMSK |= 1;   // attachINT0
  Serial.println(*data);

}
void loop()
{ Serial.println(*data);
  if (flag) {
    PORTC ^= (1 << 7); //инвертируем состояние пина
    flag = 0;
  }
  delay(2000);
  Serial.println(*data);
}

ISR(INT0_vect) { //execute ISR when fired
  Serial.println(*data);
  //EIMSK &= ~1;   // detachINT0 immediately after fired
  flag = 1;
}

А тут вывод монитора. 1 - когда касаешься проводком из пин3 к GND.

Если внимательно читать ДШ, то там написано, что EIFR чистится при исполнении прерывания. Поэтому посмотреть на него можно только в теле обработчика.



0
1
0
1
0
0
0
1
0
0
0
0
0
0

 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

wdrakula пишет:

Если внимательно читать ДШ ...

"Ну, ты, барин, задачи ставишь!"

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

а если сначала EIFR=EIFR а потом data = EIFR; и далее вывести в сериал?

alexbmd
Offline
Зарегистрирован: 15.01.2016

EIFR=EIFR обнуляет флаги если вызывать после точки срабатывания флага.  если в плане просто вывести то единственое место где они светятся это внутри тела оброботчика. wdrakula правильно поправил меня с указателем . а то я в спешке начудил там. спасибо.

"Поэтому посмотреть на него можно только в теле обработчика." и таки смотриться да. А я по началу именно туда и не поставил вывод  в монитор. почему? А если внимательно почитать даташит то пишут что в теле ни милис, ни сериал ни другие прерывания не работают. страно почему оно выводит таки в монитор...

 

 

 

wdrakula пишет:

Ты пришел с просьбой об объяснениях и помощи. Тем самым ты согласился быть в положении ниже знающих.

я разве сказал что мне ктото чем то обязан ? хотите помочь без оскарблений - помогите. упрекнуть меня в отсутсвии спасиба взамен вы не сможите. я не отрицаю что я в положении ниже знающих по _знаниям_, но не более! И терпеть помощь с унижениями не обязан в свою очередъ я.

Green
Offline
Зарегистрирован: 01.10.2015

Раз просишь - это уже унижение. Так что нефиг изображать из себя оскорблённого. А нет - ну значит не спрашивай, ищи сам в Гугле. ИМХО.

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

alexbmd пишет:

А если внимательно почитать даташит то пишут что в теле ни милис, ни сериал ни другие прерывания не работают. страно почему оно выводит таки в монитор...

Ух ты, это в каком даташите пишут что в теле ни милис, ни сериал … не работают?

И вообще, смешались в кучу кони, люди. Милис и сериал это функции, а не прерывания. И они в прерывании работают, но с некоторыми ограничениями. И вообще работа в контексте прерывания накладывает много разных ограничений, поэтому новичкам и не рекомендуют туда лезть, пока опыта не наберутся.

 

nik182
Онлайн
Зарегистрирован: 04.05.2015

Ты , это , поосторожнее в выражениях. То что они функции не мещает им использовать прерывания. Да,значения они возвращают, но если ты будешь ими пользоваться внутри своего прерывания для блинка то получишь облом, т.к. значения изменяться не будут,пока ты не выдешь из своего прерывания. Именно про это уже писали. Кроме того, если ты будешь жить в своём прерывании больше 8 микросекунд, то миллис и микросеконд будут накапливать ошибку и часики на их основе будут врать.