[uquote="AlexS4",url="/forum/viewtopic.php?p=4663792#p4663792"]
AQ29, "круги" оправданы только если вы не можете (напр по производительности) позволить себе прерывания и тогда вы сверяетесь с регистрами таймеров (time align) или весь код выстроен с баллансом всех ветвлений (что довольно трудоемко)
а если задача - простой опрос с огромным запасом по производительности то "круги"
ада это топорный колхоз, приводящий к джиттеру времени реакции от фазы луны, пропуску нажатий и пр ... или к тому что вы заменяете нормальный код на 1 единственно нужном MSC кучей доп MSC, занятых таким же корявым колхозным овнокодом. имхо.[/uquote]
Программа написана, фактически, на ассемблере для AVR. На ассемблере программа всегда либо ходит по кругу, либо переход между кругами.
Чтобы круги не превращались в ад, надо правильно писать на ассемблере.
Не помню трудностей баланса ветвлений, влияния фазы луны и прочего.
Для конкретизации - простенький пример.
Есть какой-нибудь измерительный прибор, например, вольтметр. Прибор что-то измерил и вывел на индикатор. Компьютер через USART читает данные с прибора. Есть кнопка, например, для настройки.
Упрощённо будет так:
Cycle:
Measurement ‘Вызов программы измерения
Output_Indicator ‘Вывод на индикатор
Read_Key ‘Чтение кнопок с учётом дребезга
If Bit_T = 1 Then Goto RS232 ‘Переход на обмен с компьютером
If Key = 1 Then Goto Set ‘Переход по нажатой кнопке
Goto Cycle
После выполнения программ RS232 или Set будет переход, скажем, на метку Cycle.
Прерывание только от USART, а таймеры не задействованы вообще.
Пропуск нажатия кнопки будет, но быстро будет следующий опрос, пропуск будет незаметным.
Писать просто, читать легко, полный контроль за ходом программы, отлаживать просто.
[uquote="Adrift",url="/forum/viewtopic.php?p=4663835#p4663835"]Когда начинающие пытаются поморгать светодиодом они пишут блокирующую delay(), ваш блокирующий опрос кнопок из той же серии. В простейших проектах еще ладно, зачем такое тянуть в сложные изделия с несколькими мк? Может их потому и несколько, что остальное написано в сходном стиле...[/uquote]
Не замечал проблем и в сложных изделиях с несколькими МК.
В сложных изделиях предпочитаю распределённые системы (с несколькими МК), которые имеют много преимуществ. Эти преимущества в первую очередь (и во вторую, и в третью) не связаны с кнопками и стилем.
[uquote="Adrift",url="/forum/viewtopic.php?p=4663835#p4663835"]Конкретно на AVR с таймерами может быть напряженка, но всякие ардуины, подсчитывающие ms, работают даже на tiny13 с одним таймером. Если таймер нужен для чего-то другого, то берите мк где их больше, например у 8-ми пинового ATtiny212 три таймера + RTC. Проблема комплексная, вы не только на ассме и блокирующих функциях застряли, но еще и на AVR, причем именно старых, где с периферией совсем плохо.[/uquote]
Дело, в основном, не в «напряжёнке» с таймерами. Без применения таймеров и ненужных прерываний программа проще. Зачем использовать сложный метод, когда решаемая задача допускает использовать более простой.
Для меня один метод на все случаи сомнителен.
AVR достаточно для большинства задач, зачем переходить на другое.
[uquote="Adrift",url="/forum/viewtopic.php?p=4663835#p4663835"]Не могу представить проект в котором нельзя прыгать в прерывания, но можно зависать на 120 ms )[/uquote]
Простой пример. На макетке проверяю работу какой-нибудь программы, например, той же Delay_T. С помощью отладчика надо проверить время задержки или измерить время выхода из программы по биту Т.
Программа будет состоять только из Delay_T и кнопок, которые запускают эту программу. Прерывания от таймера будут увеличивать время и искажать показания, их надо запретить.
Вообще-то в серьёзных изделиях уже давно перешёл на сенсорные кнопки, у них всё другое, начиная с фирменного вида. Обычные кнопки – это вроде как прошлый век. А на макетке стоят тактовые кнопки с их дребезгом.
[uquote="Adrift",url="/forum/viewtopic.php?p=4663835#p4663835"]Какой смысл в данном примере, если речь про саму функцию Read_Key? Зависнет она надолго или сразу вернет результат, пользоваться им можно примерно одинаково. Естественно если получили состояние кнопок за 1us, то вряд ли стоит дожидаться отпускания кнопки в блокирующем цикле)[/uquote]
Не одинаково пользоваться функцией. Если программа выскочила досрочно, то её результатами пользоваться нельзя, они аннулируются («отрезанная ветка»). Надо или перепрыгнуть, или после прерывания снова пройти по функции, например, прыгнуть на метку Cycle или на метку перед Read_Key.
[uquote="Adrift",url="/forum/viewtopic.php?p=4663835#p4663835"]Путем существенного усложнения можно сделать так чтобы из вашей блокирующей Delay_T выходило быстро, при этом все равно понадобится фоновый счетчик ms. А у вас из Delay_T выходит когда ей сигналит код требующий быстрой реакции на события, все остальное подождет. Что, например, будет если в USART прилетает байт через каждые 50ms и устанавливает флаг T? На опрос кнопок нужно минимум 60ms, получается почти все время мы будем проводить в функции опроса кнопок, при этом она никогда не будет выполняться до конца[/uquote]
Нет существенного усложнения, добавилась всего одна банальная строчка (If Bit_T = 1…).
Не нужно никаких фоновых счётчиков, всё проще, результаты функции аннулируются.
Для пояснения выше привёл пример измерителя.
В USART не может прилетать какой-то случайный байт через 50 мс, есть протокол обмена. Компьютер послал, скажем, байт адреса, и ждет, когда МК закончит свои дела, перейдёт в программу обмена и пришлёт байт готовности к обмену с компьютером. Дальше начинается обмен.
Если же надо каждые 50 мс опрашивать МК – это совсем другая задача, будет и другое решение. Неясно, зачем такому МК кнопки, возможно, проще использовать кнопки компьютера или центрального МК, у них больше сервиса, есть экран или индикатор.
[uquote="Бубоник",url="/forum/viewtopic.php?p=4663870#p4663870"]Это вы перестарались че-то. Если этот код впихнуть в цикл всей программы то:
1. При дребезге контактов строка
Сработает несколько раз.[/uquote]
Надо пояснить ситуацию.
Функция Read_Key задерживается на время, большее, чем суммарное время дребезга нажатых кнопок и выдаёт уже чистый (без дребезга) результат нажатых кнопок в переменную Key.
Поэтому не будет нескольких срабатываний Ring.
[uquote="Бубоник",url="/forum/viewtopic.php?p=4663870#p4663870"]2. При зажатой кнопке программа зависнит на строке
Код: Выделить всё
Read_Key
If Key <> 0 Then Goto L_0 ‘Жду отпускания кнопки
Так никуда не годится. А если дисплей отрисовывать, ацп данные считывать, регулировать чем то? А еще более привередлив пид регулятор ко времени.(Последнее к небольшому джитеру терпит)[/uquote]
Зависнет, конечно. Но кнопки стоят на центральном МК, а он, обычно, не занимается такими скоростными делами. У него взаимодействие с человеком, общее управление аппаратом.
У вас язык СИ, а регуляторы, да ещё скоростные, скорее всего, лучше писать на ассемблере.
У ассемблера скорость больше и полный контроль над ходом программы, это существенный плюс вообще и особенно для регулятора.