Влияние Т0 на delay()
- Войдите на сайт для отправки комментариев
Чт, 12/07/2018 - 12:56
Статей про delay() как грязи.... Но опять не пойму:
В цикле есть delay(3000). Он устраивает меня на все 100%. Пусть все зависнет. Но есть еще Таймер 0, с прерыванием. Так вот вопрос: почему в определенных случаях (разная уставка сравнения Т0) у меня дилей не работает? Код просто "проскакивает его"(((( Пробовал перед делеем ставить запрет прервания, а после снова разрешал - не помогает...
Прошу совета решения.
код покажите, только вставьте по нормальному и отформатируйте.
Так, хрен же тя, мил человек, знает, что ты там с таймером-то делаешь. Ты бы написал короткий пример, который демонмтрирует проблему, да и выложил бы его на посмотреть. Тока 100500 строк выкладывать не дада. Короткий пример напиши.
Читал, что, якобы, Т0 системно генерирует 1 мс. И она используется в делей().
Тогда вопросы: 1) Перво наперво в сети должны все писать " Делей и применение т0 недопустимо!!. Но я такого не наблюдаю... 2) Когда Т0 "перестает" быть 1мс-ундным? Когда его программно инициализируем для своих задач? 3) Если я расчитаю уставку тоже точно в 1 мс - то delay() заработает?
Т.е. проблема: у меня не работает делей() Это первично. И я предполагаю, что это связано именно с юзанием Т0. Хотя у меня куча прерываний, и код длинный, и делей может НЕ выполняться по причине другого прерывания.
Я хочу понять и исключить влияние Т0, если оно может иметь место.
Дык, таймер 0 системный. Он работу миллисов и делеев обеспечивает. Если их используешь таймер 0 лучше не трогать. Есть же первый и второй. Или сам делай пиши.
Таймер 0 генерит прерывание каждые 4 мкс.
Ну ты подтверждаешь мои предположения.... На 1 из 10 постов в сети только пишут что Т0 системный. Хотя это очень важно. Далее. Что значит "лучше не трогать"? У меня все занято((( Ок, счас попробую погуглить как программно 3 сек сделать(((
Таймер 0 генерит прерывание каждые 4 мкс.
Спасибо. Пока это мне ни о чем не говорит правда.... Внутренние что ли прерывания? Для дилей и милиса? Для меня меня прерывание - это переход в его обработчик.
Таймер 0 генерит прерывание каждые 4 мкс.
Спасибо. Пока это мне ни о чем не говорит правда.... Внутренние что ли прерывания? Для дилей и милиса? Для меня меня прерывание - это переход в его обработчик. Дя еще и при условии разрешения и т.п.
Да переход в обработчик. Уже в обработчике строят значения для микрос и миллис. Открой файлы ядра ардуино и посмотри на прерывание таймера 0.
Вот, бл.., очень тяжело посмотреть код в .../hardware/arduino/avr/cores/arduino/wiring.c !!!!!!
Вот обработчик прерывания:
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) ISR(TIM0_OVF_vect) #else ISR(TIMER0_OVF_vect) #endif { // copy these to local variables so they can be stored in registers // (volatile variables must be read from memory on every access) unsigned long m = timer0_millis; unsigned char f = timer0_fract; m += MILLIS_INC; f += FRACT_INC; if (f >= FRACT_MAX) { f -= FRACT_MAX; m += 1; } timer0_fract = f; timer0_millis = m; timer0_overflow_count++; }вот инициализация таймера: если хоть раз в жизни прочитать даташит, то это fastpwm и делитель на 64.
вот код delay()
void delay(unsigned long ms) { uint32_t start = micros(); while (ms > 0) { yield(); while ( ms > 0 && (micros() - start) >= 1000) { ms--; start += 1000; } } }===================
а теперь ВНИМАНИЕ, для таких, как ты, ТС, есть _delay_ms() прямо в arv-libc. У нее есть хитрости, но должен же ты, хоть что-то сам найти в сети.
_delay_ms()
вот это меня вполне устроило. Спасибо. В AVR6 применяю его. Не думал, что компилятор Ардуино его распознает.
Хочу заметить, что делей содержит замечательную слабую подпрограмму yield(), которую можно переопределить и во время делея заниматься чем то нужным. Т.е. заложена кое какая много задачность :-)
Не думал
Так ото ж!
Никакой многозадачности, но хук сам посебе условно полезный. Там есть только одна проблемка пользования им, а именно: время исполнения этого хука будет существенно влиять на точность delay() и она (точность) будет сильно зависеть от того, что там вызывается. А поскольку часто специально вызывать нечего, то можно (казалось бы) вызывать loop() .. ан нет, не на прямую (рекурсия, а стек не резиновый).
И вот тут, как раз и вылазит вся "условность": время исполнения того что там хотелось бы вызывать .. часто сильно недетерминировано.
P.S. На самом деле, практика показывает что стиль программирования "c delay()" - это ущербность от непонимая процессов управления и работы микроконтроллера. При нормальном автоматном подходе - "скрипач не нужен".. :)
Так нельзя же смотреть коды библиотек, в т.ч. и системных.
Тут мозгов ни у кого нет. Проверено неоднократно. :)
Бред. Методика проверки? Приборы сертифицированы? Кое у кого мозги есть, но не у всех, конечно, это точно.
Разве два килобайта - это мозги? :(
Ну, какие-никакие.
А некоторые, Архат, например, так только с восемью килобайтами работают.
Я сейчас с 96 работаю - все равно не жирно :(.
Архат уже как с год работает с 512 килобайтами .. ваще-то. :)
Так ото ж. А некоторые тут "два, два"!