delay по сути останавливает работу кода - фактически пауза а как он влияет на остальное? идет ли тактирование, работают ли счетчики и прерывания... питание по полной идет или потребление снижается? и да, есть ли способ оборвать выполнение delay не дожидаясь его окончания?
delay ничего не делает с питанием - он крутит бесконечный цикл, никакой паузы в работе кода нет, т.к. delay - это тоже код. Штатных способов оборвать выполнение delay, не дожидаясь его окончания - нет, но всегда можно допилить, при желании.
Предвосхищая вопрос "как допилить". Примерно так, как вариант: Код (C++): typedef bool (*PDelayBreakFunc)(); void myDelay(unsigned long ms, PDelayBreakFunc func) { uint32_t start = micros(); while (ms > 0) { if(func && func()) return; while ( ms > 0 && (micros() - start) >= 1000) { ms--; start += 1000; } } } bool canBreakDelay() { // тут по каким-то параметрам выясняете, что надо прервать delay if(someCondition) return true; return false; } void setup() { myDelay(5000,canBreakDelay); }
после "это цикл" всё стало на свои места. дальше можно было даже не продолжать ) спасибо. я не использую delay в коде. все на millis
На каждой итерации проверяется условие выполнения цикла. Затем выполняется пустая инструкция - nop. И так по кругу. Досрочно выйти можно через прерывание.
Вроде даже в исходниках есть заложенная возможность параллельно во время delay выполнять другой код (функция yield()), но что-то разработчики на это забили.
для прерывание бреком (как и любым иным программым методом) надо условие его срабатывание - но это уже совсем иная песня....
Также, как и везде. Вот, пожалуйста, блинк на фоне delay(100500). запускайте - мигает за милую душу. Код (C++): void setup(void) { pinMode(LED_BUILTIN, OUTPUT); } void loop(void) { delay(100500); } void yield(void) { static uint32_t startIntrval = 0; const uint32_t currentMillis = millis(); if (currentMillis - startIntrval >= 500) { startIntrval = currentMillis; digitalWrite(LED_BUILTIN, ! digitalRead(LED_BUILTIN)); } }
Открываем исходник dealy и смотрим: Код (C++): void delay(unsigned long ms) { uint32_t start = micros(); while (ms > 0) { yield(); while ( ms > 0 && (micros() - start) >= 1000) { ms--; start += 1000; } } } Очевидно, что внутренний while полностью идентичен if (зачем автор использовал while знает только он и его поставщик травы), т.е. yield() вызывается с периодом равным суммарному времени выполнения проверок во внешнем и внутреннем while'ах - достаточно часто.
Они не забыли, yield - это функция позднего связывания, я юзаю этот механизм в полный рост Другое дело, что по сути вопроса из delay досрочно вывалится штатными средствами - никак, так что yield там - просто для обеспечения возможности выполнения другого кода, пока цикл в delay крутится.
Это смотря что считать "штатными средствами". Существующий с момента "рождества С" механизм longjmp - штатное средство или не штатное? (надеюсь, тут не структурастов поблизости, а то "ой чо щас будет!!!")