Опрос кнопок микроконтроллером
Re: Опрос кнопок микроконтроллером
[uquote="shads",url="/forum/viewtopic.php?p=3613507#p3613507"]Разобрался с алгоритмом?[/uquote]
С моей точки зрения, разобрался. Немножко подшаманил на свой уровень знаний. По крайней мере он заработал, но смог я по нему определять только два вида нажатий: короткое и удержание. Но мне требовалось реализовать различную реализацию реакции системы на короткое удержание (авто повтор) и длинное (вход в режим установок). И вот тут у меня алгоритм стал давать сбои. По итогу я переделал код и стал заносить состояние кнопок в регистр. Таким образом я получил возможность отслеживать не только длительное нажатие, но и нажатие комбинации кнопок.
PS а вообще тема кнопок, на мой дилетантский взгляд, дело муторное. Ни в одном из моих проектов код опроса нажатий кнопок не повторяется. Не удается мне сделать 100% универсальный драйвер на все случаи жизни. Опыта не хватает.
Захочу, к примеру, добавить в существующий драйвер двойной клик кнопкой и больше чем уверен, что мой код опять посыпется
С моей точки зрения, разобрался. Немножко подшаманил на свой уровень знаний. По крайней мере он заработал, но смог я по нему определять только два вида нажатий: короткое и удержание. Но мне требовалось реализовать различную реализацию реакции системы на короткое удержание (авто повтор) и длинное (вход в режим установок). И вот тут у меня алгоритм стал давать сбои. По итогу я переделал код и стал заносить состояние кнопок в регистр. Таким образом я получил возможность отслеживать не только длительное нажатие, но и нажатие комбинации кнопок.
PS а вообще тема кнопок, на мой дилетантский взгляд, дело муторное. Ни в одном из моих проектов код опроса нажатий кнопок не повторяется. Не удается мне сделать 100% универсальный драйвер на все случаи жизни. Опыта не хватает.
Захочу, к примеру, добавить в существующий драйвер двойной клик кнопкой и больше чем уверен, что мой код опять посыпется
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
- Михаил7878
- Открыл глаза
- Сообщения: 57
- Зарегистрирован: Вт окт 03, 2017 20:17:02
- Откуда: Молдова
Re: Опрос кнопок микроконтроллером
Всем привет , не совсем по теме просьба нужна помощь в написании кода для тинки13 там тоже есть кнопки , готов поделится проектом кто поможет с написанием кода(сам старый и так не освоил азы программирования)
https://img.radiokot.ru/files/126168/th ... 7hjuhx.jpg
https://img.radiokot.ru/files/126168/th ... 7hpgkk.jpg
Добавлено after 10 minutes 56 seconds:
это уже собрано на других элементах но не заработало как хотелось
https://img.radiokot.ru/files/126168/me ... hq3nk1.jpg
https://img.radiokot.ru/files/126168/th ... 7hjuhx.jpg
https://img.radiokot.ru/files/126168/th ... 7hpgkk.jpg
Добавлено after 10 minutes 56 seconds:
это уже собрано на других элементах но не заработало как хотелось
https://img.radiokot.ru/files/126168/me ... hq3nk1.jpg
- главный колбасист
- Это не хвост, это антенна
- Сообщения: 1322
- Зарегистрирован: Чт авг 21, 2014 11:11:48
- Откуда: краснодарский край
- Контактная информация:
Re: Опрос кнопок микроконтроллером
"дребезг" переменного резистора отчасти лечится если используешь сдвоенный в два раза большего сопротивления,соединённые параллельно. Если в кнопке использовать не одиночный контакт,а два,три,
десять ?
десять ?
Re: Опрос кнопок микроконтроллером
[uquote="главный колбасист",url="/forum/viewtopic.php?p=4661494#p4661494"]"дребезг" переменного резистора отчасти лечится если используешь сдвоенный в два раза большего сопротивления,соединённые параллельно. Если в кнопке использовать не одиночный контакт,а два,три,
десять ?[/uquote]В общем случае - не поможет.
PS: А что такое "дребезг переменного резистора"? Неконтакт ползунка с поверхностью?
десять ?[/uquote]В общем случае - не поможет.
PS: А что такое "дребезг переменного резистора"? Неконтакт ползунка с поверхностью?
- главный колбасист
- Это не хвост, это антенна
- Сообщения: 1322
- Зарегистрирован: Чт авг 21, 2014 11:11:48
- Откуда: краснодарский край
- Контактная информация:
Re: Опрос кнопок микроконтроллером
[uquote="jcxz",url="/forum/viewtopic.php?p=4661540#p4661540"]PS: А что такое "дребезг переменного резистора"? Неконтакт ползунка с поверхностью?[/uquote]
Ну типа того. В ответственных местах дребезжащий потенциометр может беды наделать.
Это я на другом форуме подсмотрел сегодня, и пришла мысль,если это работает для потенциометра,
почему не может для кнопки ?
Ну типа того. В ответственных местах дребезжащий потенциометр может беды наделать.
Это я на другом форуме подсмотрел сегодня, и пришла мысль,если это работает для потенциометра,
почему не может для кнопки ?
Re: Опрос кнопок микроконтроллером
[uquote="главный колбасист",url="/forum/viewtopic.php?p=4661544#p4661544"]Ну типа того. В ответственных местах дребезжащий потенциометр может беды наделать.
Это я на другом форуме подсмотрел сегодня, и пришла мысль,если это работает для потенциометра,
почему не может для кнопки ?[/uquote]Потому как подключите вы хоть 100500 кнопок впараллель, при нажатии всё равно какой-то из контактов долетит первым (подлая наука механика, упругости там всякие, ..., млин), а при отжатии - последним. Они и создадут дребезг.
[uquote="главный колбасист",url="/forum/viewtopic.php?p=4661494#p4661494"]"дребезг" переменного резистора отчасти лечится если используешь сдвоенный в два раза большего сопротивления,соединённые параллельно.[/uquote]Кста - не только так. Бывают:
1. Два одинаковых R, изменяющихся в одну сторону.
2. Два разных (R и R/2), изменяющихся в одну сторону.
3. Два одинаковых R, изменяющихся в разные стороны (встречно).
4. Два разных (R и R/2), изменяющихся в разные стороны (встречно).
В прошлом проекте у нас как раз все такие варианты сдвоенных резисторов были.
Это я на другом форуме подсмотрел сегодня, и пришла мысль,если это работает для потенциометра,
почему не может для кнопки ?[/uquote]Потому как подключите вы хоть 100500 кнопок впараллель, при нажатии всё равно какой-то из контактов долетит первым (подлая наука механика, упругости там всякие, ..., млин), а при отжатии - последним. Они и создадут дребезг.
[uquote="главный колбасист",url="/forum/viewtopic.php?p=4661494#p4661494"]"дребезг" переменного резистора отчасти лечится если используешь сдвоенный в два раза большего сопротивления,соединённые параллельно.[/uquote]Кста - не только так. Бывают:
1. Два одинаковых R, изменяющихся в одну сторону.
2. Два разных (R и R/2), изменяющихся в одну сторону.
3. Два одинаковых R, изменяющихся в разные стороны (встречно).
4. Два разных (R и R/2), изменяющихся в разные стороны (встречно).
В прошлом проекте у нас как раз все такие варианты сдвоенных резисторов были.
Re: Опрос кнопок микроконтроллером
[uquote="jcxz",url="/forum/viewtopic.php?p=4661556#p4661556"]Потому как подключите вы хоть 100500 кнопок впараллель, при нажатии всё равно какой-то из контактов долетит первым (подлая наука механика, упругости там всякие, ..., млин), а при отжатии - последним. Они и создадут дребезг.[/uquote]И что? Вроде это сильно мешает фиксировать одновременное нажатие.)
Re: Опрос кнопок микроконтроллером
[uquote="OKF",url="/forum/viewtopic.php?p=4661564#p4661564"]И что? Вроде это сильно мешает фиксировать одновременное нажатие.)[/uquote]То, что сколько контактов впараллель не подключай - дребезг останется.
PS: Да и какой смысл? Дребезг легко побеждается программно.
PS: Да и какой смысл? Дребезг легко побеждается программно.
Re: Опрос кнопок микроконтроллером
[uquote="AQ29",url="/forum/viewtopic.php?p=4662376#p4662376"]Я бы не стал считать проценты производительности, а исходил из решаемой задачи.
Скажем, какой-нибудь прибор-измеритель, основной цикл – 10 мс и чётко определён, а выводить информацию на табло надо раз в секунду, чтобы цифры не мелькали. Будет цикл 10 мс или 160 мс – без разницы.
Если всё же пауза будет недопустимой, то можно сделать с прерыванием по таймеру, я ведь не против. Немного будет посложнее, но это мелочь.[/uquote]
В том и дело, что для других задач все равно придется делать по-другому, в итоге у вас будет две функции, одна из которых чуть проще, но медленнее на 4-5 порядков. Две функции лучше одной быстрой и универсальной, которую все равно придется написать?
Скажем, какой-нибудь прибор-измеритель, основной цикл – 10 мс и чётко определён, а выводить информацию на табло надо раз в секунду, чтобы цифры не мелькали. Будет цикл 10 мс или 160 мс – без разницы.
Если всё же пауза будет недопустимой, то можно сделать с прерыванием по таймеру, я ведь не против. Немного будет посложнее, но это мелочь.[/uquote]
В том и дело, что для других задач все равно придется делать по-другому, в итоге у вас будет две функции, одна из которых чуть проще, но медленнее на 4-5 порядков. Две функции лучше одной быстрой и универсальной, которую все равно придется написать?
Это так не работает, нельзя просто вызывать Delay_T и ждать, что она установит флаг через 30ms, у нее должна быть инициализация, например, текущим значением счетчика ms, а у вас две таких Delay_T. Просто выйти тоже нельзя, нужно помнить после какой из Delay_T вышли и в следующий раз начать с того же места.AQ29 писал(а): Что ж там сложного?
Будет что-нибудь вроде такого:
Delay_T 30 ms
BRTC L_0
RET
L_0:
…….. ‘Продолжение программы
Delay_T – задержка с флагом Т. При установке бита Т (регистр SREG) программа быстро выскочит из Delay_T. Встроенной такой функции пока нет (так-то есть), но появится, нередко бывает нужна.
Re: Опрос кнопок микроконтроллером
[uquote="Adrift",url="/forum/viewtopic.php?p=4662413#p4662413"]В том и дело, что для других задач все равно придется делать по-другому, в итоге у вас будет две функции, одна из которых чуть проще, но медленнее на 4-5 порядков. Две функции лучше одной быстрой и универсальной, которую все равно придется написать?[/uquote]
Область применения моего метода может оказаться довольно широкой. В ассемблере программа или ходит по кругу, или переход между кругами.
Соответственно, ограничение на применения метода – если круг слишком долгий, например, более 300 мс. Из-за этого будет затянутая реакция на кнопку - нехорошо. Но 300 мс на круг, наверно, редкая ситуация.
Кнопки обычно ставят на центральный МК. В сложных изделиях удобно использовать периферийные МК, а центральный МК выполняет функции общего управления и взаимодействия с человеком. Наверно, тут редко получается круги более 300 мс.
Одной быстрой и универсальной программы всё равно не получится, задачи бывают разные.
Таймеры могут быть заняты, а системный таймер я не использую. Мой метод удобнее.
Сейчас много занимался отладкой разных программ на макетке. И тут гораздо удобнее использовать мой метод, с его помощью кнопки легко пристроить к любой программе. В отлаживаемой программе таймеры могут быть заняты, или нельзя прыгать в прерывания и т.д. А тут быстро пристроить и никаких конфликтов.
Для наглядности приведу пример, в этой теме можно.
Есть пара кнопок (притянуты к земле, биты 0 и 1) для включения режимов Старт и Настройка (Set). Второй режим включается нажатием двух кнопок.
Команда Read_Key – считывает кнопки, результат в регистре РОН с именем Key. Верхние три строчки вставляются в круг ассемблера.
Read_Key
If Key = 1 Then Goto Start
If Key = 3 Then Goto Set
Start:
Ring ‘Пикнул звонок на нажатие кнопки
L_0:
Read_Key
If Key <> 0 Then Goto L_0 ‘Жду отпускания кнопки
……………. ‘Действия при включении режима Start.
Легко добавить другие кнопки.
Вследствие этого разговора появляется мысль сделать команду Read_Key встроенной в компилятор, это несложно, ведь она простая.
При вызове команды придётся только добавить параметры, указывающие порт, регистр Key, биты и куда притянуты кнопки, к земле или к питанию.
Тогда будет всего эти 8 банальных строчек – и всё. А тут полемика на 17 страницах.
В других методах не разбирался, достаточно было этого.
[uquote="Adrift",url="/forum/viewtopic.php?p=4662413#p4662413"]Это так не работает, нельзя просто вызывать Delay_T и ждать, что она установит флаг через 30ms, у нее должна быть инициализация, например, текущим значением счетчика ms, а у вас две таких Delay_T. Просто выйти тоже нельзя, нужно помнить после какой из Delay_T вышли и в следующий раз начать с того же места.[/uquote]
Надо пояснить ситуацию.
Delay_T не включает бит Т, а постоянно анализирует его. Если бит Т установился в 1, то за несколько ассемблерных команд программа выскакивает из задержки. А бит Т устанавливается в прерывании от какого-то события.
Это нужно для следующего.
Скажем, компьютер (или центральный МК) через USART послал запрос (обычно это адрес) в МК. Возникло прерывание, в котором устанавливается бит Т. Вследствие этого программа быстро выскакивает из задержки Delay_T (где-то за указанную 1 мкс) и переходит к общению с компьютером.
Если же использовать обычную задержку Delay, то компьютеру пришлось бы ждать 30 мс до начала общения, это долго.
Сам компьютер вообще-то бывает очень нетороплив в общении, несмотря на свои гигагерцы и гигабайты.
«Из какого Delay_T вышел» и «начать с того же места» - это вы правильно заметили.
Я не стал это описывать, получается много текста и там было не по теме.
Ассемблер – язык гибкий, много вариантов решения.
В подпрограмму я не возвращаюсь, это проблемно. Обычно использую метод «отрезанной ветки». Скажем, программа ходит по основному кругу. В этом круге была вызвана одна подпрограмма, та вызвала другую и т.д. При возникновении прерывания, например, по установленному биту Т, возвращаюсь в основной круг путём закрытия всех вызванных подпрограмм и перехожу к общению с компьютером.
Бит Т может быть занятым. В этом плане считаю, что должны быть 3 разных задержки с флагом.
Одна с битом Т, как уже рассматривалась.
Другая с битом регистра РОН, назначаемым пользователем.
Третья с битом регистра РВВ, тоже назначаемым пользователем. В последнем случае можно даже не прыгать в прерывание. Установился бит прерывания, по нему можно выскочить из задержки без входа в прерывание.
Иногда удобно ввести переменную, в которой указывается, что надо делать после выхода на основной круг.
Область применения моего метода может оказаться довольно широкой. В ассемблере программа или ходит по кругу, или переход между кругами.
Соответственно, ограничение на применения метода – если круг слишком долгий, например, более 300 мс. Из-за этого будет затянутая реакция на кнопку - нехорошо. Но 300 мс на круг, наверно, редкая ситуация.
Кнопки обычно ставят на центральный МК. В сложных изделиях удобно использовать периферийные МК, а центральный МК выполняет функции общего управления и взаимодействия с человеком. Наверно, тут редко получается круги более 300 мс.
Одной быстрой и универсальной программы всё равно не получится, задачи бывают разные.
Таймеры могут быть заняты, а системный таймер я не использую. Мой метод удобнее.
Сейчас много занимался отладкой разных программ на макетке. И тут гораздо удобнее использовать мой метод, с его помощью кнопки легко пристроить к любой программе. В отлаживаемой программе таймеры могут быть заняты, или нельзя прыгать в прерывания и т.д. А тут быстро пристроить и никаких конфликтов.
Для наглядности приведу пример, в этой теме можно.
Есть пара кнопок (притянуты к земле, биты 0 и 1) для включения режимов Старт и Настройка (Set). Второй режим включается нажатием двух кнопок.
Команда Read_Key – считывает кнопки, результат в регистре РОН с именем Key. Верхние три строчки вставляются в круг ассемблера.
Read_Key
If Key = 1 Then Goto Start
If Key = 3 Then Goto Set
Start:
Ring ‘Пикнул звонок на нажатие кнопки
L_0:
Read_Key
If Key <> 0 Then Goto L_0 ‘Жду отпускания кнопки
……………. ‘Действия при включении режима Start.
Легко добавить другие кнопки.
Вследствие этого разговора появляется мысль сделать команду Read_Key встроенной в компилятор, это несложно, ведь она простая.
При вызове команды придётся только добавить параметры, указывающие порт, регистр Key, биты и куда притянуты кнопки, к земле или к питанию.
Тогда будет всего эти 8 банальных строчек – и всё. А тут полемика на 17 страницах.
В других методах не разбирался, достаточно было этого.
[uquote="Adrift",url="/forum/viewtopic.php?p=4662413#p4662413"]Это так не работает, нельзя просто вызывать Delay_T и ждать, что она установит флаг через 30ms, у нее должна быть инициализация, например, текущим значением счетчика ms, а у вас две таких Delay_T. Просто выйти тоже нельзя, нужно помнить после какой из Delay_T вышли и в следующий раз начать с того же места.[/uquote]
Надо пояснить ситуацию.
Delay_T не включает бит Т, а постоянно анализирует его. Если бит Т установился в 1, то за несколько ассемблерных команд программа выскакивает из задержки. А бит Т устанавливается в прерывании от какого-то события.
Это нужно для следующего.
Скажем, компьютер (или центральный МК) через USART послал запрос (обычно это адрес) в МК. Возникло прерывание, в котором устанавливается бит Т. Вследствие этого программа быстро выскакивает из задержки Delay_T (где-то за указанную 1 мкс) и переходит к общению с компьютером.
Если же использовать обычную задержку Delay, то компьютеру пришлось бы ждать 30 мс до начала общения, это долго.
Сам компьютер вообще-то бывает очень нетороплив в общении, несмотря на свои гигагерцы и гигабайты.
«Из какого Delay_T вышел» и «начать с того же места» - это вы правильно заметили.
Я не стал это описывать, получается много текста и там было не по теме.
Ассемблер – язык гибкий, много вариантов решения.
В подпрограмму я не возвращаюсь, это проблемно. Обычно использую метод «отрезанной ветки». Скажем, программа ходит по основному кругу. В этом круге была вызвана одна подпрограмма, та вызвала другую и т.д. При возникновении прерывания, например, по установленному биту Т, возвращаюсь в основной круг путём закрытия всех вызванных подпрограмм и перехожу к общению с компьютером.
Бит Т может быть занятым. В этом плане считаю, что должны быть 3 разных задержки с флагом.
Одна с битом Т, как уже рассматривалась.
Другая с битом регистра РОН, назначаемым пользователем.
Третья с битом регистра РВВ, тоже назначаемым пользователем. В последнем случае можно даже не прыгать в прерывание. Установился бит прерывания, по нему можно выскочить из задержки без входа в прерывание.
Иногда удобно ввести переменную, в которой указывается, что надо делать после выхода на основной круг.
Re: Опрос кнопок микроконтроллером
AQ29, "круги" оправданы только если вы не можете (напр по производительности) позволить себе прерывания и тогда вы сверяетесь с регистрами таймеров (time align) или весь код выстроен с баллансом всех ветвлений (что довольно трудоемко)
а если задача - простой опрос с огромным запасом по производительности то "круги" ада это топорный колхоз, приводящий к джиттеру времени реакции от фазы луны, пропуску нажатий и пр ... или к тому что вы заменяете нормальный код на 1 единственно нужном MSC кучей доп MSC, занятых таким же корявым колхозным овнокодом. имхо.
а если задача - простой опрос с огромным запасом по производительности то "круги" ада это топорный колхоз, приводящий к джиттеру времени реакции от фазы луны, пропуску нажатий и пр ... или к тому что вы заменяете нормальный код на 1 единственно нужном MSC кучей доп MSC, занятых таким же корявым колхозным овнокодом. имхо.
Re: Опрос кнопок микроконтроллером
[uquote="AQ29",url="/forum/viewtopic.php?p=4663778#p4663778"]Соответственно, ограничение на применения метода – если круг слишком долгий, например, более 300 мс. Из-за этого будет затянутая реакция на кнопку - нехорошо. Но 300 мс на круг, наверно, редкая ситуация.
Кнопки обычно ставят на центральный МК. В сложных изделиях удобно использовать периферийные МК, а центральный МК выполняет функции общего управления и взаимодействия с человеком. Наверно, тут редко получается круги более 300 мс.[/uquote]
Когда начинающие пытаются поморгать светодиодом они пишут блокирующую delay(), ваш блокирующий опрос кнопок из той же серии. В простейших проектах еще ладно, зачем такое тянуть в сложные изделия с несколькими мк? Может их потому и несколько, что остальное написано в сходном стиле...
Кнопки обычно ставят на центральный МК. В сложных изделиях удобно использовать периферийные МК, а центральный МК выполняет функции общего управления и взаимодействия с человеком. Наверно, тут редко получается круги более 300 мс.[/uquote]
Когда начинающие пытаются поморгать светодиодом они пишут блокирующую delay(), ваш блокирующий опрос кнопок из той же серии. В простейших проектах еще ладно, зачем такое тянуть в сложные изделия с несколькими мк? Может их потому и несколько, что остальное написано в сходном стиле...
Конкретно на AVR с таймерами может быть напряженка, но всякие ардуины, подсчитывающие ms, работают даже на tiny13 с одним таймером. Если таймер нужен для чего-то другого, то берите мк где их больше, например у 8-ми пинового ATtiny212 три таймера + RTC. Проблема комплексная, вы не только на ассме и блокирующих функциях застряли, но еще и на AVR, причем именно старых, где с периферией совсем плохо.AQ29 писал(а):Одной быстрой и универсальной программы всё равно не получится, задачи бывают разные.
Таймеры могут быть заняты, а системный таймер я не использую. Мой метод удобнее.
Не могу представить проект в котором нельзя прыгать в прерывания, но можно зависать на 120 ms )AQ29 писал(а):Сейчас много занимался отладкой разных программ на макетке. И тут гораздо удобнее использовать мой метод, с его помощью кнопки легко пристроить к любой программе. В отлаживаемой программе таймеры могут быть заняты, или нельзя прыгать в прерывания и т.д. А тут быстро пристроить и никаких конфликтов.
Какой смысл в данном примере, если речь про саму функцию Read_Key? Зависнет она надолго или сразу вернет результат, пользоваться им можно примерно одинаково. Естественно если получили состояние кнопок за 1us, то вряд ли стоит дожидаться отпускания кнопки в блокирующем цикле )AQ29 писал(а):Для наглядности приведу пример, в этой теме можно.
Есть пара кнопок (притянуты к земле, биты 0 и 1) для включения режимов Старт и Настройка (Set). Второй режим включается нажатием двух кнопок.
Команда Read_Key – считывает кнопки, результат в регистре РОН с именем Key. Верхние три строчки вставляются в круг ассемблера.
Read_Key
If Key = 1 Then Goto Start
If Key = 3 Then Goto Set
Start:
Ring ‘Пикнул звонок на нажатие кнопки
L_0:
Read_Key
If Key <> 0 Then Goto L_0 ‘Жду отпускания кнопки
……………. ‘Действия при включении режима Start.
Легко добавить другие кнопки.
Вследствие этого разговора появляется мысль сделать команду Read_Key встроенной в компилятор, это несложно, ведь она простая.
При вызове команды придётся только добавить параметры, указывающие порт, регистр Key, биты и куда притянуты кнопки, к земле или к питанию.
Тогда будет всего эти 8 банальных строчек – и всё. А тут полемика на 17 страницах.
Ясно, я совсем другое имел в виду. Путем существенного усложнения можно сделать так чтобы из вашей блокирующей Delay_T выходило быстро, при этом все равно понадобится фоновый счетчик ms. А у вас из Delay_T выходит когда ей сигналит код требующий быстрой реакции на события, все остальное подождет. Что, например, будет если в USART прилетает байт через каждые 50ms и устанавливает флаг T? На опрос кнопок нужно минимум 60ms, получается почти все время мы будем проводить в функции опроса кнопок, при этом она никогда не будет выполняться до конца )AQ29 писал(а):Delay_T не включает бит Т, а постоянно анализирует его. Если бит Т установился в 1, то за несколько ассемблерных команд программа выскакивает из задержки. А бит Т устанавливается в прерывании от какого-то события.
Это нужно для следующего.
Скажем, компьютер (или центральный МК) через USART послал запрос (обычно это адрес) в МК. Возникло прерывание, в котором устанавливается бит Т. Вследствие этого программа быстро выскакивает из задержки Delay_T (где-то за указанную 1 мкс) и переходит к общению с компьютером.
Если же использовать обычную задержку Delay, то компьютеру пришлось бы ждать 30 мс до начала общения, это долго.
Сам компьютер вообще-то бывает очень нетороплив в общении, несмотря на свои гигагерцы и гигабайты.
«Из какого Delay_T вышел» и «начать с того же места» - это вы правильно заметили.
Я не стал это описывать, получается много текста и там было не по теме.
Ассемблер – язык гибкий, много вариантов решения.
Re: Опрос кнопок микроконтроллером
Это вы перестарались че-то. Если этот код впихнуть в цикл всей программы то:AQ29 писал(а):Read_Key
If Key = 1 Then Goto Start
If Key = 3 Then Goto Set
Start:
Ring ‘Пикнул звонок на нажатие кнопки
L_0:
Read_Key
If Key <> 0 Then Goto L_0 ‘Жду отпускания кнопки
1. При дребезге контактов строка
Код: Выделить всё
Ring ‘Пикнул звонок на нажатие кнопки2. При зажатой кнопке программа зависнит на строке
Код: Выделить всё
Read_Key
If Key <> 0 Then Goto L_0 ‘Жду отпускания кнопкиПо лучше так будет
Код: Выделить всё
....Начало цикла основной программы
timer++;
if(timer>100)//делает временную задержку чтобы не обрабатывать часто кнопки
{//и избегает дребезг контактов
timer=0;
if((!right)&&(!uder_r))
{
uder_r=1;
//выполнение кода при нажатии кнопки
}else if(right)uder_r=0;
}
....Продолжение цикла основной программы
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Опрос кнопок микроконтроллером
Ну может человек боится прерываний, не умеет нормально писать обработчики... Прерывания тогда могут зависать, крашить всю программу.... А вы сразу "не могу представить..." ))))))))Adrift писал(а):Не могу представить проект в котором нельзя прыгать в прерывания
Напряженка может быть, если нужно генерировать много аппаратных ШИМ-сигналов, например. Или какие то другие события, которые должны быть синхронизированы аппаратным таймером. А в подавляющем большинстве случаев достаточно иметь один таймер, который молотит с определенным периодом. А от него уже можно делать сколько угодно программных таймеров. Timer-driven events )))Adrift писал(а):Конкретно на AVR с таймерами может быть напряженка
Вон в простой абдурине на 328 меге все таймеры системно заняты для нужд AnalogWrite. А все остальное решается через программные таймеры.
Белая и Пушистая
Re: Опрос кнопок микроконтроллером
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4664792#p4664792"]Ну может человек боится прерываний, не умеет нормально писать обработчики...[/uquote]
Если не используешь прерывания, но тем более нужно стараться писать максимально быстрый нигде подолгу не зависающий код, особенно если еще и критикуешь ЯВУ за недостаточную эффективность )
ps. Я, кстати, вспомнил, что AQ29 на easyelectronics свой "современный ассемблер", который пока нигде нельзя списать, еще в 2017 рекламировал. По идее общедоступная версия уже должна быть на подходе )
Если не используешь прерывания, но тем более нужно стараться писать максимально быстрый нигде подолгу не зависающий код, особенно если еще и критикуешь ЯВУ за недостаточную эффективность )
У tiny13 один 8-bit таймер, если шимить на полной скорости, то использовать его для отсчета времени как минимум не очень удобно. Другое дело, что этому tiny13 уже 20 лет и давно можно было подыскать ему более подходящую замену )Just_Fluffy писал(а):Напряженка может быть, если нужно генерировать много аппаратных ШИМ-сигналов, например.
ps. Я, кстати, вспомнил, что AQ29 на easyelectronics свой "современный ассемблер", который пока нигде нельзя списать, еще в 2017 рекламировал. По идее общедоступная версия уже должна быть на подходе )
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Опрос кнопок микроконтроллером
На какие только ухищрения не приходится идти, что б только не выносить опрос кнопок в отдельную псевдопараллельную задачу.
Adrift,
По факту оказалось, что этот его современный ассемблер - обычный АлгоритмБилдер. И команда логарифма - макрос, считающий приближенный логарифм.
Adrift,
Ну для каждой задачи нужно подбирать МК, представляя сначала в голове, что и как будет работать и куда раскидать аппаратные ресурсы. Если уже никак иначе - то обработчик прерывания писать, в котором программный делитель сделать и далее уже отдавать в основной цикл флажок...Adrift писал(а):один 8-bit таймер, если шимить на полной скорости
Спойлер
Да где он только его не рекламировал. Здесь тоже. Доказывал мне, что логарифм с флоатами на ЯВУ - вчерашний день. А в его современном ассемблере (для АВРок) логарифм вычисляется одной командой!!!Adrift писал(а): AQ29 на easyelectronics свой "современный ассемблер", еще в 2017 рекламировал
По факту оказалось, что этот его современный ассемблер - обычный АлгоритмБилдер. И команда логарифма - макрос, считающий приближенный логарифм.
Белая и Пушистая
Re: Опрос кнопок микроконтроллером
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4664905#p4664905"]По факту оказалось, что этот его современный ассемблер - обычный АлгоритмБилдер.[/uquote]
В принципе, если речь не про среду разработки целиком, то ассемблер сам по себе не настолько сложная для написания программа, может там что-то свое по аналогии с АБ и написали. Я последний раз такое делал буквально неделю назад. Проги на ассме для Pico2 компилируются во время компиляции проги на C++, правда там всего десяток инструкций, не считая псевдо-инструкций )
В принципе, если речь не про среду разработки целиком, то ассемблер сам по себе не настолько сложная для написания программа, может там что-то свое по аналогии с АБ и написали. Я последний раз такое делал буквально неделю назад. Проги на ассме для Pico2 компилируются во время компиляции проги на C++, правда там всего десяток инструкций, не считая псевдо-инструкций )
Re: Опрос кнопок микроконтроллером
[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. При зажатой кнопке программа зависнит на строке Так никуда не годится. А если дисплей отрисовывать, ацп данные считывать, регулировать чем то? А еще более привередлив пид регулятор ко времени.(Последнее к небольшому джитеру терпит)[/uquote]
Зависнет, конечно. Но кнопки стоят на центральном МК, а он, обычно, не занимается такими скоростными делами. У него взаимодействие с человеком, общее управление аппаратом.
У вас язык СИ, а регуляторы, да ещё скоростные, скорее всего, лучше писать на ассемблере.
У ассемблера скорость больше и полный контроль над ходом программы, это существенный плюс вообще и особенно для регулятора.
а если задача - простой опрос с огромным запасом по производительности то "круги" ада это топорный колхоз, приводящий к джиттеру времени реакции от фазы луны, пропуску нажатий и пр ... или к тому что вы заменяете нормальный код на 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. При дребезге контактов строка
Код: Выделить всё
Ring ‘Пикнул звонок на нажатие кнопкиНадо пояснить ситуацию.
Функция Read_Key задерживается на время, большее, чем суммарное время дребезга нажатых кнопок и выдаёт уже чистый (без дребезга) результат нажатых кнопок в переменную Key.
Поэтому не будет нескольких срабатываний Ring.
[uquote="Бубоник",url="/forum/viewtopic.php?p=4663870#p4663870"]2. При зажатой кнопке программа зависнит на строке
Код: Выделить всё
Read_Key
If Key <> 0 Then Goto L_0 ‘Жду отпускания кнопкиЗависнет, конечно. Но кнопки стоят на центральном МК, а он, обычно, не занимается такими скоростными делами. У него взаимодействие с человеком, общее управление аппаратом.
У вас язык СИ, а регуляторы, да ещё скоростные, скорее всего, лучше писать на ассемблере.
У ассемблера скорость больше и полный контроль над ходом программы, это существенный плюс вообще и особенно для регулятора.
Re: Опрос кнопок микроконтроллером
[uquote="AQ29",url="/forum/viewtopic.php?p=4664954#p4664954"]Программа написана, фактически, на ассемблере для AVR. На ассемблере программа всегда либо ходит по кругу, либо переход между кругами.[/uquote]Это у вас "программа ходит кругами". А грамотные разработчики уже давно свои программы пишут в стиле "event-driven".
И язык тут не играет никакой роли.
И язык тут не играет никакой роли.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Опрос кнопок микроконтроллером
Можно подумать, event-driven программа квадратами ходит...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!