Форум РадиоКот https://radiokot.ru/forum/ |
|
Вопрос по программированию задержки внутри прерывания https://radiokot.ru/forum/viewtopic.php?f=57&t=196331 |
Страница 1 из 9 |
Автор: | electroget [ Сб янв 11, 2025 09:15:30 ] |
Заголовок сообщения: | Вопрос по программированию задержки внутри прерывания |
Доброго времени суток уважаемые коты. Сам я в программировании специалистом совсем не являюсь, поэтому хочу спросить мнение у специалистов. Накропал для Ардуины вот такой код: СпойлерКод: LiquidCrystal_I2C lcd(0x27,20,4); // Подключаем дисплей volatile bool intFlag = false; unsigned long delayFront; // Переменная для времени задержки включения выхода void setup() { interrupts(); lcd.init(); lcd.backlight();// Включаем подсветку дисплея lcd.clear(); // очистить дисплей lcd.setCursor(0,0); lcd.print("Setting A"); lcd.setCursor(0,1); lcd.print("Delay mS"); lcd.setCursor(0,2); lcd.print("Voltage V"); lcd.setCursor(0,3); lcd.print("Carrent A"); delayFront == 0; Serial.begin(9600); pinMode(2,INPUT); pinMode(3,OUTPUT); pinMode(7,INPUT); pinMode(8,INPUT); pinMode(9,INPUT); pinMode(10,INPUT); digitalWrite(3,LOW); attachInterrupt(0, event, RISING); } void event() {intFlag = true;} void loop() { if(digitalRead(7)==HIGH)delayFront=1; if(digitalRead(8)==HIGH)delayFront=2; if(digitalRead(9)==HIGH)delayFront=5; if(digitalRead(10)==HIGH)delayFront=10; Serial.println(delayFront); lcd.setCursor (12, 1); lcd.print(delayFront); lcd.print(" "); if (intFlag) { intFlag = false; // сбрасываем флаг ЗДЕСЬ ДОЛЖНА БЫТЬ ФУНКЦИЯ ЗАДЕРЖКИ НА [b]delayFront[/b] МИЛЛИСЕКУНД digitalWrite(3,HIGH); // включение выхода Serial.println("Interrupt!"); } } Этот код должен делать вот что. После прихода фронта импульса на цифровой вход 2, возникшее прерывание с задержкой на delayFront миллисекунд должно включить цифровой выход 3. В статьях по программированию Ардуины пишут, что при выполнении прерываний функции времени работают с некими ограничениями. Какую функцию программирования мне следует использовать для того чтоб получать необходимую задержку включения выхода? P.S. Задержка включения выхода нужна на десятки и даже сотни миллисекунд. Поэтому delayMicroseconds(time) получается что не подходит. |
Автор: | veso74 [ Сб янв 11, 2025 10:51:08 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
delay() не работает в interrupt, а micros() и millis() не меняет свое значение в interrupt, но все три функции работает вне interrupt. Насколько критично время импульса? Также обработайте ситуацию: в течение времени после прерывания произошло новое прерывание (в зависимости от алгоритма вашего устройства: 1. оно должно или 2. не должно продлить время или проигнорировать новое прерывание). В первом варианте снова пропустите временной период, а во втором случае можете просто остановить прерывания cli(); и продолжить позже sei();. |
Автор: | electroget [ Сб янв 11, 2025 11:01:08 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
delay() не работает в interrupt, а micros() и millis() не меняет свое значение в interrupt, но все три функции работает вне interrupt. То есть, если я уже после обработки прерывания вставлю код с функцией millis() и после этого дам команду digitalWrite(3, HIGH); то межу прерыванием и включением выхода 3 получится необходимый мне интервал времени задержки? |
Автор: | veso74 [ Сб янв 11, 2025 11:04:54 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
Да. При наличии флага в прерывании реакця будет задержана на несколько такт, пока не войдет в loop. Вот почему спросил о критичности времени. Есть вариации на включения в прерывание и выключения в цикле по истечении времени. Выбирайте согласно своему алгоритму. --- Реакция мог бы быть с задержки - вижу, что пшете сообщения в Serial в цикле без каких-либо условий. |
Автор: | electroget [ Сб янв 11, 2025 11:10:30 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
veso74, Точность вообще не критична. Это делается для установки времени задержки срабатывания электронного предохранителя. Интервалы будут задаваться внешним переключателем: 1,2,5,10,50,100,200 миллисекунд. Скажите, а выполнение прерывания нужно обязательно специальной командой останавливать? В каком месте кода её нужно вставлять? |
Автор: | veso74 [ Сб янв 11, 2025 11:13:45 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
Для предохранителя: измените проверки if .. if ... if на if ... else if ... else if ... или на switch-case. И lcd.print и Serial.println() - ето медленные функции. Напишите их хотя бы с условием, что не пишет каждой раз в loop. Одно сообщение не даст объяснения ![]() |
Автор: | electroget [ Сб янв 11, 2025 11:18:54 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
lcd.print и Serial.println() - ето медленные функции. Напишите их хотя бы с условием, что не пишет каждой раз в loop. Это я всё конечно уберу когда программа заработает как надо. Вы мне пожалуйста ещё скажите про прекращение работы прерывания. Выполнение прерывания нужно обязательно специальной командой останавливать? В каком месте кода её нужно вставлять? |
Автор: | veso74 [ Сб янв 11, 2025 11:26:56 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
Это решите сами. Зависит от выбранного алгоритма. noInterrupts(); или cli(); -> запрещаем прерывания interrupts(); или sei(); -> разрешаем прерывания |
Автор: | electroget [ Сб янв 11, 2025 11:33:49 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
veso74, Понял, спасибо. Буду пробовать сделать. |
Автор: | codenamehawk [ Сб янв 11, 2025 12:38:08 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
veso74 писал(а): delay() не работает в interrupt, И с каких это пор она не работает в прерывании? Работает и в прерывании. Для коротких отрезков времени можете ее использовать, "the delay() function and many sketches use short delays for such tasks as switch debouncing, the use of delay() in a sketch has significant drawbacks. No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function, so in effect, it brings most other activity to a halt." https://docs.arduino.cc/language-refere ... ime/delay/ |
Автор: | smacorp [ Сб янв 11, 2025 12:55:26 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
Не надо делеить в обработчиках прерываний. Независимо от способа. Это учит плохому. Это будет говнокод. |
Автор: | OKF [ Сб янв 11, 2025 13:05:34 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
in a sketch has significant drawbacks. No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function, so in effect, it brings most other activity to a halt." Ну почему же). Внутри delay() есть yield() - функция позднего связывания. Определив её у себя, можно выполнять операции во время работы delay(). Добавлено after 4 minutes 3 seconds: delay() в interrupt прекратит interrupt. Да ладно! Вы невнимательны.) |
Автор: | BOB51 [ Сб янв 11, 2025 13:06:58 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
Ардуино под Си не ассемблер. Используем то, что принято в референсе. Прерывание предпочтительно только под короткие операции с флагами и/или короткие фрагменты программного кода. Для слишком критичного ко времени исполнения участка подпрограммы-обработчика под ассемблером есть прием "условного возврата" (подстановка адреса возврата через стек). Возможно нечто похожее можно и под Си (без вставок на ассемблере) получить... ![]() А вот этим yield() для простых прожек баловаться как то... https://alexgyver.ru/lessons/time/ Тем более, что без подключения соответствующей библиотеки ( #include <Scheduler.h> ) yield() работать не будет... Второе... "...расположенный внутри неё (yield()) код будет выполняться во время работы любой задержки delay() в программе..." но это не одно и то же, что "расположенная внутри функции текущего обработчика прерывания функция delay() будет исполняться"... ![]() |
Автор: | codenamehawk [ Сб янв 11, 2025 13:24:47 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
veso74 писал(а): delay() в interrupt прекратит interrupt. Не прекратит, а CLi не разрешит другие прерывания. Для точности временной задержки delay заменить на свою задержку. smacorp писал(а): Не надо делеить в обработчиках прерываний. Независимо от способа. Это учит плохому. Это будет говнокод. Если работает, то это никому не мешает. Добавлено after 3 minutes 51 second: OKF писал(а): Внутри delay() есть yield() - функция позднего связывания. Определив её у себя, можно выполнять операции во время работы delay(). Это предупреждение тем (и не мое), которые этого не знают. |
Автор: | veso74 [ Сб янв 11, 2025 13:26:08 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
Считайте условно нерабочим как происходит действие, которое не было запланировано. (не воспринимайте слово "прекратит" буквально, часто пользуюсь переводчиком). |
Автор: | codenamehawk [ Сб янв 11, 2025 13:29:46 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
При входе в прерывание, другие прерывания запрещены и делай их не разрешит, только выход из прерывания или вручную. |
Автор: | BOB51 [ Сб янв 11, 2025 13:40:51 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
Тем самым в определенной степени будет нарушена работа устройства. ![]() Псевдопараллельный процесс можно организовать как на дополнительном прерывании по COMP_A (у атмег 328 не задействован референсом) так и на сцепке стандартного референса - используя tone и любое из внешних прерываний для подсчета поступающих на вход прерывания импульсов. Правда там два вывода теряем плюс внешняя перемычка. ![]() |
Автор: | shonty [ Сб янв 11, 2025 14:07:44 ] |
Заголовок сообщения: | Re: Вопрос по программированию задержки внутри прерывания |
BOB51 писал(а): Для слишком критичного ко времени исполнения участка подпрограммы-обработчика под ассемблером есть прием "условного возврата" (подстановка адреса возврата через стек). BOB51, можно это в коде выразить?
|
Страница 1 из 9 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |