Если у меня в программе по какой-то причине главный цикл будет зависать, я смогу дописать вывод вспомогательной инфы на индикатор, и так отловить проблему. В вашем варианте всегда будет светиться один из сегментов, и то, если повезет, отладочный вывод в вашем варианте уже невозможен. Но, повторяю: каждый имеет право на веревку достаточной длины, чтобы выстрелить себе в ногу... Я не посягаю на это священное право!
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Ну это же ваши проблемы.) А у меня свои. И не надо про верёвку, вроде как вы учитель.) Я, конечно, прислушиваюсь, но каждый сам находит что для себя оптимально.
Добавлено after 5 hours 14 minutes 43 seconds: Вспомнил, однако, когда мне пришлось делать динамическую индикацию в основном цикле... Когда я делал собственную реализацию ScopeClock... из-за очень больших задержек на вход-выход от прерываний для этого пришлось отказаться, и весь векторный кадр пришлось рисовать в главном цикле при запрещенных прерываниях...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Ну если уже подходить к вопросу принципиально, то главный цикл может быть привязан к какому то "системному таймеру" и молотить строго через определенные интервалы времени. Тогда динамическую индикацию можно дергать и в основном цикле (при условии, что все подзадачи укладываются в период цикла) Я встречала и противоположный подход - в основной программе только инициализация периферии. И все. А вся логика - в прерывании таймера. В принципе, оба подхода имеют право на жизнь. Но программа может стать сложночитаемой, когда одна большая простыня кода.
ARV, Если все задачи главного цикла выполняются заведомо быстрее периода систика, то джиттер будет в несколько тактов. Просто обновление дисплея нужно поставить в самом начале суперцикла. При частоте систика в 1-2-4 кГц - эти несколько тактов заметны не будут. Но тогда нужно думать и дробить задачи. Так как даже запись в ЕЕПРОМ с блокирующим ожиданием флага готовности может все поломать. Поэтому мой подход обычно - все тайминго-критичное ( динамическая индикация, отслеживание каких то периферийных процессов, критичных ко времени и т.д.; туда же обычно и кнопки уходят) - оно живет отдельно, в прерывании систика, со своими конечными автоматами, невидимыми из суперцикла. А в самом суперцикле - отслеживание флагов от периферии, а для вывода - заполнение видеопамяти. Тогда можно себя не ограничивать в редких "долгоиграющих" задачах типа записи в ЕЕПРОМ. Где то кто то писал (может даже и вы) - все медленное, отвечающее за работу с внешним миром - в основной программе, все критичное ко времени - на прерываниях. И взаимодействие с основным миром - через флаги.
OKF писал(а):
Именно так. Никаких простыней.)
У меня так не получается ))) Поскольку любое состояние устройства - это как отдельный режим/подрежим. И вся логика тут же дробится на кучку switch(mode) {}.... внутри суперцикла Часть этих свичей уходят в функции.... Но в суперцикле у меня остается минимум два свича по режимам - один - это таймаут текущего режима и переход к следующему, второй - это загрузка/перезагрузка таймаута для текущего режима. Спойлер
while (1) {// super loop uint8_t ticks; do ticks = getSysClockInterval(); while(!ticks);
//---------- переменные на один раз modeType newMode = mode; uint8_t reloadTimeOut = 0;
//---------- exec peripherial
//---------- Timeout if ( mode == newMode && modeTimeOut ) { modeTimeOut--; if ( !modeTimeOut) { switch (newMode) { case mtInit: //newMode = mtShowTime; break; } // switch newmode } // if ( !modeTimeOut) } // if modeTimeOut
//---------- New or Reload timeout if (mode != newMode) reloadTimeOut = 1;
if (reloadTimeOut) { switch (newMode) { case mtInit: modeTimeOut = 1; break; } // switch newmode } // if reloadTimeOut
//---------- Mode change if (mode != newMode) { mode = newMode; } // if (mode != newMode)
} // while (1) - super loop
}
Зачастую еще в суперцикле живет обработчик нажатий на кнопки. Мне так удобнее.
Хотя в последнее время мне больше нравится концепция событий от периферии и от программных таймеров. Тогда программа дробится на вагон мелких обработчиков событий.
Всё так, пока в главном цикле код линейный, либо пока из-за прерываний джиттер systick не станет неприемлемым
Код заведомо короче системного периода. Джиттера нет, потому что нет прерываний. И я не агитирую за индикацию в основном цикле, но зачастую так проще. Там же и кнопки и всё остальное. Конечно это для простых конструкций. Да, и отладочный вывод на тот же индикатор почему не возможен? Это же быстро всё.
Кто-нибудь может сказать. avr-gcc при работе с eeprom библиотечными функциями из eeprom.h (типа eeprom_update_byte() и т.п.) сам запрещает прерывания на время обновления? Что-то я задумался, посмотрел ассемблерный код и не могу сообразить, давно асмом не пользовался, а там все понамешано.... Вроде cli есть, а восстановление предыдущего состояния не вижу. Хотя программы всегда работали без вопросов.
ks0, обычно сначала куда то сохраняется SREG, потом CLI, потом защищенный блок и потом восстановление SREG - тогда вернется состояние запрета прерываний как было до входа в защищенный блок. И вроде как eeprom_update_byte() не запрещает прерывания, там тупой блокирующий цикл ожидания готовности...
Заголовок сообщения: Re: WinAvr в вопросах и ответах
Добавлено: Сб янв 31, 2026 17:17:54
Открыл глаза
Карма: 1
Рейтинг сообщений: 2
Зарегистрирован: Пт фев 22, 2013 01:51:30 Сообщений: 52 Откуда: украина николаев
Рейтинг сообщения:0
Добрый день установил WinAvr, пытаюсь скомпилировать код для тиньки 2313а , вылазит ошиибка y_test.c:166: error: 'TIMSK1' undeclared (first use in this function) Подскажите что не так Заранее спасибо
Вложения:
Комментарий к файлу: настройки WinAvr Makefile.rar [5.73 KiB]
Скачиваний: 15
Комментарий к файлу: исходник my_test.c [1.99 KiB]
Скачиваний: 24
Заголовок сообщения: Re: WinAvr в вопросах и ответах
Добавлено: Вс фев 01, 2026 00:06:45
Открыл глаза
Карма: 1
Рейтинг сообщений: 2
Зарегистрирован: Пт фев 22, 2013 01:51:30 Сообщений: 52 Откуда: украина николаев
Рейтинг сообщения:0
Огромное спасибо , прошло
Добавлено after 5 hours 42 minutes 13 seconds: Если не сложно , есть проект барометра , выдает показание в Мбар что очень не удобно Помогите переписать на мм ртутного столба весь вечер убил ,не выходит т.к. нет основ в С Формула с куском другого проекта с формулой { //*Pr = (bmp.sealevel(P,ALTITUDE)) * 0.7500637554192; // сохраняем значение давления в мм.рт.ст. (над уровнем моря) *Pr = P * 0.7500637554192; // сохраняем значение давления в мм.рт.ст. return true; // возврат true } Заранее спасибо , если интересно выложу схему подключения для ардуинки
Заголовок сообщения: Re: WinAvr в вопросах и ответах
Добавлено: Вс фев 01, 2026 13:17:28
Открыл глаза
Карма: 1
Рейтинг сообщений: 2
Зарегистрирован: Пт фев 22, 2013 01:51:30 Сообщений: 52 Откуда: украина николаев
Рейтинг сообщения:0
для точной калибровки я изменял высоту над уровнем моря ,не знаю в чем запарка но показания были 960 а по факту 765ммHg , использовал программу погоды для лоцманов (она точнее всех)
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения