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

RainMan
Offline
Зарегистрирован: 21.06.2011

Ребята подскажите пожалуйста, естть в Ардуине внутренние прерывания. В своеих источниках их не обнаружил, и коммант для их обработки тоже не нашел 

RainMan
Offline
Зарегистрирован: 21.06.2011

спасибо. Уже нашел статью по этому поводу 

Alexander
Offline
Зарегистрирован: 25.04.2010

Я здесь оставлю на всякий случай http://arduino.ru/Tutorial/Arduino_Interrupts

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

RainMan пишет:

спасибо. Уже нашел статью по этому поводу 

 

Подскажи пожалуйста, как? или ссылку на статью...

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

Alexander пишет:

Я здесь оставлю на всякий случай http://arduino.ru/Tutorial/Arduino_Interrupts

 

там нет нислова про внутренние прерывания

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

arduinoandatmega8 пишет:

там нет нислова про внутренние прерывания

Не говорите ерунды. С самой же первой строки речь о прерываниях по таймеру - это и есть те самые "внутренние прерывания", которые вы ищете

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

b707 пишет:

arduinoandatmega8 пишет:

там нет нислова про внутренние прерывания

Не говорите ерунды. С самой же первой строки речь о прерываниях по таймеру - это и есть те самые "внутренние прерывания", которые вы ищете

там нет примеров как это сделать... всё сухо для новичка

а на второй странице внешние прерывания только рассмотрены в примере

подскажите кусок кода плиз?

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

вот например:



unsigned char temp;

void setup() 

{

pinMode(13, OUTPUT); 

pinMode(9, INPUT); 

digitalWrite(9, HIGH); // под. резистор

}

void loop() 

{

if ( digitalRead(9) == HIGH )

{ temp = temp+1; 

delay(100);

}

if (temp >10 )

{digitalWrite(13, HIGH);

temp = 0; 

}

}



нужно чтоб переменная темп, сбрасывалась в 0 каждые две секунды.

Как это сделать?

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

arduinoandatmega8 пишет:



нужно чтоб переменная темп, сбрасывалась в 0 каждые две секунды.

Как это сделать?

Изучайте, там и примеры есть - https://playground.arduino.cc/Main/MsTimer2

Alexander
Offline
Зарегистрирован: 25.04.2010

arduinoandatmega8 пишет:

вот например:



unsigned char temp;

void setup() 

{

pinMode(13, OUTPUT); 

pinMode(9, INPUT); 

 

.....

Изучите
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

unsigned char temp;

void setup() 

{

pinMode(13, OUTPUT); 

pinMode(9, INPUT); 

digitalWrite(9, HIGH); // под. резистор

}

void loop() 

{

if ( digitalRead(9) == HIGH )

{ temp = temp+1; 

delay(100);

}

if (temp >10 )

{digitalWrite(13, HIGH);

temp = 0; 

}

}

Как сделать, чтобы переменная темп обнулялось каждые 2 секунды?

т.е. чтобы выполнялось команда 

temp = 0;

каждые 2 секунды?

 

 

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

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

arduinoandatmega8 пишет:



нужно чтоб переменная темп, сбрасывалась в 0 каждые две секунды.

Как это сделать?

Изучайте, там и примеры есть - https://playground.arduino.cc/Main/MsTimer2

там внешнию библиотеку ещё подлючают...

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

arduinoandatmega8 пишет:

Как сделать, чтобы переменная темп обнулялось каждые 2 секунды?

т.е. чтобы выполнялось команда 

temp = 0;

каждые 2 секунды?

Чувствую. что вам еще рано прерывания изучать. тем более что для такой ерунды они и не нужны совсем. Почитайте, как сделать блинк без делей http://arduino.ru/tutorials/BlinkWithoutDelay

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

b707 пишет:

arduinoandatmega8 пишет:

Как сделать, чтобы переменная темп обнулялось каждые 2 секунды?

т.е. чтобы выполнялось команда 

temp = 0;

каждые 2 секунды?

Чувствую. что вам еще рано прерывания изучать. тем более что для такой ерунды они и не нужны совсем. Почитайте, как сделать блинк без делей http://arduino.ru/tutorials/BlinkWithoutDelay

 

да мне не для этих целей. это я просто как пример привел.

Если точнее, мне нужно в коде IR приемника, чтобы при нажатии кнопки пульта происходил счёт, если за две секунды кнопка нажата N раз, выполнить действие. Если кнопка на пульте нажата менее N раз за 2 секунды, сбросить отсчет и ничего не делать (ждать новых нажатий и считать их)

 

#include <IRremote.h>

int RECV_PIN = 2; //вход ИК приемника
IRrecv irrecv(RECV_PIN);
decode_results results;
int LED = 9;


void setup()

{
irrecv.enableIRIn(); // включить приемник
pinMode(LED, OUTPUT);

}

void loop() {
 

if (irrecv.decode(&results))
{
  if (results.value == 0x20DF8E7) //код моей кнопки "2FD807F". У Вас он будет дугой
  {
    digitalWrite(LED, HIGH);
  }
    if (results.value == 0x20DF4EB)//код моей кнопки "2FD40BF". У Вас он будет дугой
    {
      digitalWrite(LED, LOW);
    }
    
       
      
    
 irrecv.resume();
}
}

 

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016
unsigned char temp;

void setup() 

{

pinMode(13, OUTPUT); 

pinMode(9, INPUT); 

digitalWrite(9, HIGH); // под. резистор

}

void loop() 

{
static uint32_t om = millis(); //Old Millis
uint32_t nm = millis(); //New Millis

if ( nm - om > 2000)  //2000 ms = 2s Time Interval
   {
   om = nm; //restart timer
   temp = 0; // do what you really want $)
   }

if ( digitalRead(9) == HIGH )

{ temp = temp+1; 

delay(100);

}

if (temp >10 )

{digitalWrite(13, HIGH);

temp = 0; 

}

}

 

 В Ардуино, специально для чайников, уже сделали ОДНО прерывание по таймеру, в котором считается время. Во всех задачах привязанных ко времени никакие прерывания не нужны, если точность в несколько миллисекунд устраивает.

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

arduinoandatmega8 пишет:

там внешнию библиотеку ещё подлючают...

А что, Ваша религия этого не позволяет? Ну, тогда изучите, что делает эта библиотека, и пишите этот же код сами.

arduinoandatmega8
Offline
Зарегистрирован: 25.07.2017

Большое Вам спасибо! 

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

#include <avr/interrupt.h>
volatile boolean flag = 0;
//mega 32u4
void setup()
{
DDRD = 0; PORTD = 1; //input PULL-UP and default state is ‘1’ for INT0 PD0
DDRC = 0xFF; //output for Led PC7
EICRA &= ~3;  // clear existing INT0 flags
EICRA |= 1;   // 0:LOW,1:CHANGE,2:FALLING,3:RISING bytes for INT0
EIMSK |= 1;   // enable INT0
sei();        //проверить нужен ли он для прерывания????*******???????*****
}
 void loop()
    {
        if (flag){
        PORTC^=(1<<7); //инвертируем состояние пина
        flag=0;
        }
     }

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

ставлю обычный ардуиновский пример и работает. делают вот этот свой и  какой то затык. что я забыл ?

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

1. А что Вы делаете-то? Вернее, пытаетесь делать?

2. Что за "обычный пример". Обычным только стиральный порошой бывает. Показывайте.

И, кстати, кто Вам сказал, что строка 16 инвертирует там что-то? Не верьте, Вас обманули.

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

alexbmd, в 7 и 16 строке у вас разные пины.

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

Да точно :) но теперь другая проблема

после бутлоадера сразу загорается лед (ну допустим наводки float state хотя страно у меня же там пул-ап) но вот потом от простого замыкания пина на землю ничего не происходит. не срабатывает прерывание. пытаюсь добиться такого же результата как тут. тут я просто замыкаю пин на землю и инвертируется led state 

const byte ledPin = 13;
const byte interruptPin = 3;
volatile byte state = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
  digitalWrite(ledPin, state);
}

void blink() {
  state = !state;
}

Евгений непонял насчёт 16строчки , вы хотели сказать что XOR не инвертирует??

Green
Онлайн
Зарегистрирован: 01.10.2015

Смотря что понимать под внутренними. Внутренние программные или внутренние аппаратные? Программных в АVR нет, но иногда хочется.) И тогда приходится жертвовать ногой.(

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

alexbmd пишет:

Евгений непонял насчёт 16строчки , вы хотели сказать что XOR не инвертирует??

Каментарий дописать надо

PORTC^=(1<<7); //инвертируем состояние 7 бита и обнуляем остальные

Green
Онлайн
Зарегистрирован: 01.10.2015

Нет, просто писать нужно по нормальному, а не с магическими цифрами. Тогда таких дурных ошибок бы небыло.

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

DetSimen пишет:

PORTC^=(1<<7); //инвертируем состояние 7 бита и обнуляем остальные

почему ?

			Инверсия отдельных бит
 Исходное значение	10001000
 Операция		^
 Битовая маска		11000000
 Результат		01001000

 

Green
Онлайн
Зарегистрирован: 01.10.2015

Каментарий дописать надо)

PORTC^=(1<<7); //инвертируем состояние несуществующего 7 бита PORTC

alexbmd
Offline
Зарегистрирован: 15.01.2016
#include <avr/interrupt.h>
volatile boolean flag = 0;
//mega32u4
void setup()
{
DDRD = 0; PORTD = 1; //input PULL-UP and default state is ‘1’ for INT0 PD0
DDRC = 0xFF; //output for Led PC7
EICRA &= ~3;  // clear existing INT0 flags
EICRA |= 1;   // 0:LOW,1:CHANGE,2:FALLING,3:RISING bytes for INT0
EIMSK |= 1;   // enable INT0
sei();        //проверить нужен ли он для прерывания????*******???????*****
}
 void loop()
    {
        if (flag){
        PORTC^=(1<<7); //инвертируем состояние пина
        flag=0;
        }
     }

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

что я забыл в этом коде? почему не срабатывает как ардуиновский?

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

Green пишет:

 //инвертируем состояние несуществующего 7 бита PORTC

почему не существующего?

Green
Онлайн
Зарегистрирован: 01.10.2015

Чукча писатель.( Потому, что коль вы адресуете порты напрямую, нужно перед этим изучить архитектуру этого МК. Кстати, плата какая?

Green
Онлайн
Зарегистрирован: 01.10.2015

А вообще, жаль что нет как у большого брата, типа INT 13h).
И того же приоритета прерываний, как у какого то x51.(

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

alexbmd пишет:

DetSimen пишет:

PORTC^=(1<<7); //инвертируем состояние 7 бита 

почему ?

			Инверсия отдельных бит
 Исходное значение	10001000
 Операция		^
 Битовая маска		11000000
 Результат		01001000

 

Да, ты прав, я стормозил спрасони

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

Green пишет:

 Кстати, плата какая?

atmega32u4 

так почему не существуещего ? порта С нет у а атмеги? 

[off]я уже на XOR три разных ответа тут услышал теперь про несуществующий порт С

0x3A29[/off]

Onkel
Offline
Зарегистрирован: 22.02.2016

порт С есть, PC6 и PC7 нет.

 Port C (PC5:0)
          Port C is a 7-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The PC5...0 output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port C pins that are     externally pulled low will source current if the pull-up resistors are activated. The Port C pins are tri-stated whеn a     reset condition becomes active, even if the clock is not running.

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

Не удивительно, что три разных .. на разных камнях Атмела - разная конфигурация портов, где-то есть и даже порт K а где-то и порт С неполон.. :)

Про 32u4 ничего не скажу, не смотрел ни разу..

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

Onkel пишет:

порт С есть, PC6 и PC7 нет.

 

https://www.arduino.cc/en/Hacking/PinMapping32u4

а D13 это что ?

Green
Онлайн
Зарегистрирован: 01.10.2015

alexbmd пишет:

atmega32u4 

так почему не существуещего ? порта С нет у а атмеги? 

[off]я уже на XOR три разных ответа тут услышал теперь про несуществующий порт С

0x3A29[/off]

Ну, так с этого надо было бы и начинать. У 32u4, в отличие от 328, как раз выведены только PC6 и PC7.
А вообще, непонятен смысл прямого обращения к портам. Ардуино и как раз для того что бы не сушить мозг с ними.
И что бы D13 был и в Африке D13!

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

Arhat109-2 пишет:

 

Про 32u4 ничего не скажу, не смотрел ни разу..

да там практически тоже самое. лед тоже на D13 но PC7 а не B5 как у мега328. регистры теже (или почти теже). но не суть, пускай код будет для мега 328 он всеравно не обрабатывает прерывания через регистры. гдето чтото я упустил. но что?!

 

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

Коллеги, в микре PC7 есть, мало того, на нём уже висит штатный светдиод :) Ему соответствует 13й арду-пин.

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

мне кажется, в коде #26 сообщения reti() не нужно. Не уверен, что оно мешает, но необходимости в нем не вижу

 

А что касается вопроса "Почему не работает" - по-моему. ответ очевидный. Никогда не надо забегать вперед в обучении. 

alexbmd  - если вы не знаете даже, как вычислить остаток от деления на 2000 - то куда вам прерывания? Кто знает. что за косяки вы допустили в начальном конфигурировании регистров при таком общем уровне знаний? - начните с мигания диодами. освоения миллис и прочих простых вещей - вам для обучения на полгода хватит

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

[off]вопрос не про led :) давайте вообщем забудем этот лед. вопрос почему не срабатывает прерывание[/off]

чукчи, три разных XOR, несуществующие порты и millis в регистре внешнео прерывания уже были. что дальше :)

по делу ктото может ответить - почему не срабатывает прерывание?

reti() и sei() не мешает. особенно если учесть что глобальные прерывания изначально включены в камнях. так для подстраховки.

код что на экране это весь код. никаких дополнительных регистров нету. а надо?


#include <avr/interrupt.h>
volatile boolean flag = 0;
//mega32u4
void setup()
{
DDRD = 0; PORTD = 1; //input PULL-UP and default state is ‘1’ for INT0 PD0
DDRC = 0xFF; //output for Led PC7
PORTC &= ~(1<<7);
//attachInterrupt()
EIMSK &= ~1;  // detachINT0
EICRA &= ~3;  // clear existing INT0 flags
EICRA |= 1;   // 0:LOW,1:CHANGE,2:FALLING,3:RISING for INT0
EIFR   = 1;   // clear flag INT0 for event fired before attachINT0
EIMSK |= 1;   // attach ISR for INT0
}
 void loop()
    {
        if (flag){
        PORTC^=(1<<7); //инвертируем состояние пина
        flag=0;
        }
     }

ISR(INT0_vect){ //execute ISR when it fired
		flag = 1;
}
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

reti() - точно не нужен, но конкретно в этом контексте мешать не должен. Там сохранять нечего, она практически naked и так. Врядли там стек плывет куда-то.. если честно, то смотрю на код и нифига не могу понять чего оно не работает .. может у 32u4 какие-то ещё регистры по работе с прерываниями не включены тут? Блин, куда уж проще-то..

Green
Онлайн
Зарегистрирован: 01.10.2015

Ну, а почему не написать по людски? Хотя бы так.

const int btPin  = 2;                   //int0!
const int ledPin = 13;


volatile bool flag;

void setup()
{
  pinMode(btPin, INPUT_PULLUP);         //INT0 pullup
  pinMode(ledPin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(btPin), pinChange, CHANGE);
}


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


void pinChange()
{
  flag = true;
}

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

На 32U4 INT0 на другой ноге

Green
Онлайн
Зарегистрирован: 01.10.2015

Ну вот. Хотел было посмотреть, но лень.)
В моём примере должно работать, потому как 2 это INT1.

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

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

 

Green
Онлайн
Зарегистрирован: 01.10.2015

Во, во. Зато "по делу ктото может ответить - почему не срабатывает прерывание?")
Боюсь, что даже спасибо не услышим.(

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

Green пишет:

Ну, а почему не написать по людски? Хотя бы так.


 

потому что так работает. я же это написал выше :)

так работает а через регистры нет.  в даташите пишут надо EIMSK вначале обнулить единицей. но мы и так когда его активируем пишем в него единицу , еще раз записать в него единицу перед установкой EICRA не думаю что поможет :)

[off] Green b707 да неважно на какой ноге 2, 3 я не бездумно копирую код я исправляю если надо. вы можете писать хоть 10. суть в другом. не работает через регистры итить колотить[/off]

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

b707 пишет:

 что там наконфигурил автор

 

вы видите на экране еще какието конфигураторы? потому что их нет. что вы видите в скетче то и на конфигурировал автор. может уже хватит все шишки на автора валить :)

 

делаю все одинаково. через attach (мой пример выше) работает

через регистры (мой пример выше) не работает

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

alexbmd пишет:

b707 пишет:

 что там наконфигурил автор

 

вы видите на экране еще какието конфигураторы? потому что их нет. что вы видите в скетче то и на конфигурировал автор. может уже хватит все шишки на автора валить :)

делаю все одинаково. через attach (мой пример выше) работает

через регистры (мой пример выше) не работает

значит что-то неправильно, DIMAX да и Евгений Петрович однозначно знают в чём косяк )))

pinMode(2,INPUT_PULLUP); // подтяжка кнопки "режим энкодера"
EICRA=1<<ISC01; //int0 -falling mode
EIMSK=1; //int0 enable

 

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

Вы заинтриговали уже совсем. У меня нет Леонардо (она?) на 32u4, поэтому могу попробовать проверить Ваш пример только на Мега (и та нестандарт) или НАНО .. но боюсь что он заработает после перестановки ножек согласно даташиту.

Green
Онлайн
Зарегистрирован: 01.10.2015

alexbmd пишет:

через регистры (мой пример выше) не работает

Ну так делайте по частям. Уберите аттач сначала. Вместо него поставьте
 

  EICRA &= ~(1<<ISC01);
  EICRA |= 1<<ISC00;                    //0:LOW, 1:CHANGE, 2:FALLING, 3:RISING bytes for INT0
  EIFR   = 1<<INT0;
  EIMSK |= 1<<INT0;

Затем уже играйтесь LED и кнопкой.