Задержки в прерываниях

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

Надо в прерывании поочередно переводить в 1/0 три пина, с определённой задержкой.

Таймеры тоже использовать не получается, конструкция готова.

И как выкрутиться? 

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

delay(100500)

 

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

Не работает delay в прерываниях, к сожалению. 

ssss
Offline
Зарегистрирован: 01.07.2016

Добавить ещё три ардуины и всё получится.

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

Vlad_rx пишет:

Не работает delay в прерываниях, к сожалению. 

С какого это он перепугу не работает? Откройте маску прерываний и всё заработает.

sei();
delay(100500);

И всё.

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

Ну разрешим прерывания и что? В мануале сказано, что delay в обработке прерываний не работает.

В железе, кстати, тоже не работает.

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ну а вопрос то в чем ? После входа в прерывание, запускаете таймер, который гененрит прерывания для обработки вашей задачи, в таймерном прерывании делаете все что хотите.

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

Какой таймер?

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

Vlad_rx пишет:

Ну разрешим прерывания и что? В мануале сказано, что delay в обработке прерываний не работает.

В железе, кстати, тоже не работает.

У всех Всё отлично работает, Видимо Вы один такой :))))

Жругое дело, что устраивать задержки в прерываниях .... ну, если Вам надо ...

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

Ожидал совет, а не ехидство.

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

Vlad_rx пишет:

Ожидал совет, а не ехидство.

Какой совет Вы ожидали? По задержкам в обработчике прерывания? Их там нельзя делать! Делэй там отлично работает, но задержки в обработчике делать нельзя - это крайне безграмотно.

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

Любые же советы по организации таких задержек (с делэй или ещё как) изначально безграмотны.

ssss
Offline
Зарегистрирован: 01.07.2016

Vlad_rx пишет:

Ожидал совет, а не ехидство.

"Ты первый начал!"(с)... ибо толком ничего не сказал.

ssss
Offline
Зарегистрирован: 01.07.2016

Vlad_rx пишет:

Надо в прерывании поочередно переводить в 1/0 три пина, с определённой задержкой.

С какой? Микросекунды, миллисекунды, минуты, часы? С какой точностью это всё должно выдерживаться?

Цитата:

Таймеры тоже использовать не получается, конструкция готова.

А нужно было думать ДО, а не ПОСЛЕ! Что, и программного нет?

Цитата:

И как выкрутиться? 

Посыпать голову пеплом! Или неправвильный алгоритм, или неправильный выбор камня.

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

Так. Сначала.

При изменении уровня на INT0 должны последовательно появиться 1 на трёх пинах, интервал 10 мС.

При следующем изменении уровня - сняться 1 в обратном порядке, интервал 5 мС.

MagicianT
Offline
Зарегистрирован: 03.10.2015

Недавно мне тож нужна была задержка, для драйва сенсора пыли от Шарпа, ну так я её в прерыжание и вставил. Не такая большая как Вам надо, но можете растянуть:

  volatile uint16_t timerdl =  0;  

  int16_t temp  = ADCL;  
          temp += (ADCH << 8);  
  accumul += temp;

  PORTB  &= ~(pin_Led);    // pin Low             
  timerdl = 315;           // wait 280
  while(timerdl--){ }      // do countdown 1.13 count/ usec
  ADCSRA |= (1<<ADSC);     // start conv.
  timerdl = 45;            // wait 40
  while(timerdl--){ }   
  PORTB  |= pin_Led;       // pin High         

 

Logik
Offline
Зарегистрирован: 05.08.2014

Vlad_rx пишет:

Так. Сначала.

При изменении уровня на INT0 должны последовательно появиться 1 на трёх пинах, интервал 10 мС.

При следующем изменении уровня - сняться 1 в обратном порядке, интервал 5 мС.

Так и в чем проблема? Из обработчика INT0 стартуете любой свободный таймер на генерацию прерывания через 10 мсек и в глобальную переменную запишете 0. В обработчике прерывания таймера в зависимости от переменной подымаете пины и инкрементите переменную. Как досчитаете до трех - запрет прерывания таймера. Если нет свободных таймеров - цепляетесь на таймер системного времени (ищите по форуму, была спецтема про этот грязный хак) и с дополнительным делителем на 10 (впрочем, на той же глобальной переменной) делаете тоже самое, только таймер в конце не выключаете. Гасить - аналогично. А если код писали грамотно, и требования к точности временных интервалов адекватные, то вобще в лупе все решается.

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

Какая может быть задержка между прерыванием и первым изменением пина? Может быть в прерывании просто выставить флаг и в основном цикле уже щелкать пинами? 10 мс уж очень большое время, что бы заморативаться на задержку в прерывании. Если это не приемлимо можно взять свободный таймер, в прерывании зарядить его на 10 или 5 мс и уже в прерывании таймера щелкать пинами. Про софт задержку вам уже сказали. Вариантов решения много. Это как как с измерением высоты барометром - можно давление мерить, а можно как кирпич босать.    

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

Спасибо. Вечером попробую.

Logik
Offline
Зарегистрирован: 05.08.2014

nik182 пишет:

 Это как как с измерением высоты барометром - можно давление мерить, а можно как кирпич босать.    

Ага. Но то все не наш подход. Но наш метод - прикладывать барометр к измеряемому предмету снизу вверх  подсчитывая сколько их влезет и получить высоту сразу в барометрах )))) 

Vlad_rx
Offline
Зарегистрирован: 26.09.2016

В результате сделал проще. У меня два прерывания 0 и 1, 0 работает по изменению уровня, а 1 по низкому и только в случае если на 0 низкий уровень. Всего три варианта. В обработке прерываний присвоил вариантам номера 1, 2, 3. В лупе проверяется какой вариант. Вставил в корпус и посмотрел время срабатывания реле, сделал секундомер для этого, все уложилось в разброс времени срабатывания реле, а это микросекунды.