Прерывание Ардуино УНО по состоянию пинов

Roman2344
Offline
Зарегистрирован: 09.09.2015

Вообщем есть Ардуино УНО задействовал я два прерывания по 2 и 3 пину( основные стандартные прерывания для УНО) через регистры EICRA EIMSK.EICRA, по другому как здесь  пишут http://arduino.ru/Reference/AttachInterrupt

через переменную volatile, и команду 

 

attachInterrupt

не работало . Ну это всё не важно, важно то что мне нужно третье прерывание использовать, для этого хочу использовать 10 пин, вычитал я что есть  прерывание по состоянию пинов, для этого как я понял нужно инициализировать #define PCINT10_vect, и всё и оно будет работать по изменению состояния на 10 пине? А как тогда сделать так что бы при изменении состояния на 10 пине только с 0 в 1 срабатывало прерывание?

 

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

Roman2344,  если вы про PCINT прерывания, то они не умеют райзинг. Но прерывание компаратора может, я про него не так давно писал.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Спасибо. 

Я так понял мне нужно так прописать для 10пина, мне нужно что бы при переходе с 0 в 1 и припереходе с 1 в 0 у меня при одно переходе работал один цикл подпрограммы, а при переходе 1 в 0, другой цикл что бы работал:


01

void setup(){

02




03

PORTD|=1<<10; // 10 пин ард. -вход с подтяжкой

04

ACSR=(0<<ACD)|(1<<ACBG)|(1<<ACIE)|(ACIS1>>1)|(1<<ACIS0);



05

// включить компаратор, сравнение с ион, включить прерывание,

06

//срабатывание по по появлению 1 или 0 на 10 пине.



07

}

08




09

ISR (ANALOG_COMP_vect) {

10


Вот мне нужно выполнять постоянный цикл подпрограммы после того как произошло прерывание по 10 пину:

именно этот цикл:

if (  digitalRead (zaliv) == 1){

  delay(40);



if(digitalRead (urovenpust) < 1 && digitalRead (urovenpol) < 1 && digitalRead (urovenpoln) < 1) {

 delay(30);

  lcd.setCursor(3, 0); //

lcd.print("bak pust");// 

  lcd.setCursor(14, 0);

  lcd.printByte(6);

    lcd.setCursor(15, 0);

 lcd.printByte(7);

    lcd.setCursor(14, 1);

  lcd.printByte(8);

    lcd.setCursor(15, 1);

  lcd.printByte(9);

digitalWrite(outcompressor, 0);

digitalWrite(outfire, 0);

delay(1000);

lcd.clear();// Очистка дисплея

return;}



if(  digitalRead (urovenpust) == 1 && digitalRead (urovenpol) < 1 && digitalRead (urovenpoln) < 1 ){

delay(30);

  lcd.setCursor(5, 0); //

lcd.print("Zaliv");//

lcd.setCursor(0, 1); //

lcd.print("Malo topliva");//  

  lcd.setCursor(14, 0);

   lcd.printByte(6);

    lcd.setCursor(15, 0);

  lcd.printByte(7);

    lcd.setCursor(14, 1);

    lcd.printByte(12);

    lcd.setCursor(15, 1);

 lcd.printByte(13);

 digitalWrite(outcompressor, 0);

digitalWrite(outfire, 0);

delay(1000);

lcd.clear();// Очистка дисплея

return;}



if(  digitalRead (urovenpust) == 1 && digitalRead (urovenpol) == 1 && digitalRead (urovenpoln) < 1 ){

delay(30);



  lcd.setCursor(5, 0); //

lcd.print("Zaliv");// 

lcd.setCursor(0, 1); //

lcd.print("Polovina baka");//  

  lcd.setCursor(14, 0);

   lcd.printByte(6);

    lcd.setCursor(15, 0);

    lcd.printByte(7);

    lcd.setCursor(14, 1);

    lcd.printByte(2);

    lcd.setCursor(15, 1);

 lcd.printByte(3);

 digitalWrite(outcompressor, 0);

digitalWrite(outfire, 0);

delay(1000);

lcd.clear();// Очистка дисплея

return;}

if(  digitalRead (urovenpust) == 1 && digitalRead (urovenpol) == 1 && digitalRead (urovenpoln) == 1 ){

  delay(20);

  

 lcd.setCursor(5, 0); //

lcd.print("Zaliv");// 

lcd.setCursor(2, 1); //

lcd.print("Polniy bak");// 

  lcd.setCursor(14, 0);

   lcd.printByte(2);

    lcd.setCursor(15, 0);

   lcd.printByte(3);

    lcd.setCursor(14, 1);

    lcd.printByte(2);

    lcd.setCursor(15, 1);

    lcd.printByte(3);

 digitalWrite(outcompressor, 0);

digitalWrite(outfire, 0);

delay(1000);

lcd.clear();// Очистка дисплея

return;}

}

После того как  произойдёт прерывание при переходе с 1 в 0 по 10 пину, должен выполняться другой цикл. Вот пишут же что нельзя в прерываниях задержки, а мне без них никак, второе, я не понял регистры ACSR ACD ACBG ACIE ACIS1 ACIS0, это регистры аналогового компаратора? Тогда если мне кроме 10 ноги нужно ещё к примеру 11 нога эти же регистры использовать? Регистры ACIS1 ACIS0 – это регистры для настройки на срабатывание на 1 или 0?

 

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

Roman2344, советую почитать даташит. Все прерывания сидят на конкретных ногах, никаких "хочу на 10й ноге" тут быть не может. Компаратор - на 7 ноге. Задержки в прерываниях не используются в принципе. С задержками и прочими долгопроцессами  велкам в loop()

Roman2344
Offline
Зарегистрирован: 09.09.2015

То есть для УНО тогда получается 3 прерывания и всё, как я понял прерывание по компаратору, не делает общий сброс как обычные прерывания по 2 и 3 пинам? Просто по 2 и 3 пинам прерывания чем хороши, что у меня в Сетапе прописаны условия и циклы, и когда по 2 или 3 ноге прерывание оно делает общий сброс, проверяет условие и в цикле остаётся пока условие не изменится, вот я  так понял по прерыванию компаратора так не возможно?

Почему тогда в статьяъ пишут про:

PCINT

Что на этих ногах можно прерывание по состоянию данных пинов делать, чуть ли не всех? Это наверное только для Ардуино на Атмеге 2560 или как там тот контроллер не помню уж.

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

Roman2344, если даташит пугает, то посмотрите сюда прерывания PCINT висят почти на каждом пине, и группируются по 8 штук на один вектор. Программно можно сделать на PCINT и райзинг и фаллинг, и вообще многое чего.  Всё зависит от конкретной задачи и опыта программиста.

arduinec
Offline
Зарегистрирован: 01.09.2015

Судя по примерам, события там происходят достаточно медленно. Зачем тогда прерывания использовать? Просто в цикле опрашиваются входные пины (много раз в секунду) и, в зависимости от сигналов на них, предпринмаются нужные действия.

Если же очень хочеться использовать прерывания, то внутри подпрограммы обработки прерывания выставляется флаг типа flag1=true, который и обрабатывается в основном цикле и потом сбрасываеьтся (flag1=false).

 

mag155
Offline
Зарегистрирован: 21.12.2017

Всем привет! А  как подключить сразу два прирывания вот так все работае 

attachInterrupt(0, detect_up, FALLING); 

А вот так не хочет в чем проблема ?

attachInterrupt(1, detect_up, FALLING); 

 

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

в чем выражаеца "не работает"?

mag155
Offline
Зарегистрирован: 21.12.2017

Не реагирует на прирывание. Переключаю провод с одного пина на второц и не работает.

void setup() {
  Serial.begin(9600);
  pinMode(dimPin, OUTPUT);
   pinMode(dimPin1, OUTPUT);
  digitalWrite(dimPin, 0);
  digitalWrite(dimPin1, 0);
  pinMode(zeroPin, INPUT);              
  attachInterrupt(0, detect_up, FALLING); 

  StartTimer1(timer_interrupt, 40);      
  StopTimer1();                        

Меняю на 1 и не работает.

mag155
Offline
Зарегистрирован: 21.12.2017

По ходу вход 3 не рабочий. На нем обычный шим тоже не работает .