| Ассемблер AVR C++ Pascal | Все листинги Мои листинги Добавить листинг |
Репозиторий
Мигалка
Автор VobarЯзык: Ассемблер AVR
Опубликовано 15 мая 2012 года в 19:19
Через декремент 2х регистров в подпрограмме построена задержка, которая вставляется между включением/выключением линий портов С и В. Мигает все нормально, кроме 6 и 3 линий обоих портов, на них стабильно держится уровень лог. еденицы.
Мой вариант
Автор dsd_corpЯзык: C++
Опубликовано 4 мая 2012 года в 09:21
Я не проверял, могут быть косяки, писал тупо в лоб сходу.
Идея в следующем(ТЗ под мой вариант):
- На выходе мы получаем два байта: битовую маску комманды и количество нажатий в последовательности.
Типа такого: [маска 0b00100110, нажатий 6]: значит было короткое нажатие, два длинных, еще два коротких и одно длинное. То есть в битмапе каждый поднятый бит - длинное нажатие, не поднятый - короткое. По большому счету нам не надо смотреть потом по битам, достаточно реагировать на предопределенные паттерны, то есть тупо на числа по сути.
Например:
#define CMD_MENU 0x01
if (bt_result==CMD_MENU) ...
- Есть таймаут ожидания ввода комманды(последовательности). Рулится дефайнами(#define release_timeout 100), через 2секунды(release_timeout*scan_interval) после последнего отпускания кнопки будет сброс состояния. Перед сбросом будет попытка выполнить комманду, если таковая была предопределена.
Можно этот таймаут сократить, если систему команд сделать такой, чтобы в определенный момент после любого последнего в команде нажатия уже точно определить что комманда совпала, и не ждать таймаута.
- Ограничение максимального количества нажатий на комманду(#define command_max_len). Если у нас все комманды максимум из четырех нажатий, нет смысла ждать таймаута или нажатия 8 раз для заполнения всего байта и начала обработки комманды. При использовании байта(u08 bt_result) абсолютный максимум нажатий в одной команде получается 8.
Собственно обработка конца комманды выполняется функцией check_bit_map(). Я ее код не приводил. В моем коде ее вызов в двух местах, при чем в первом еще и результат этой функции обрабатывается(совпало или нет). Ну там по комментариям должно быть понятно.
То есть в результате мы не просто считаем сколько коротких и сколько длинных, а еще и знаем их последовательность.
Описание работы.
Переменная bt_time имеет двойное предназначение. Она знаковая.
Когда кнопка нажата, она работает счетчиком длины(времени) нажатия. Максимально эта длина 127(в знаковом байте дальше считать некуда). Когда счетчик достигает этого значения, он перестает считать, но продолжает индицировать нажатие. Типа уперлись в бесконечность.
Когда кнопка отпускается, эта переменная начинает отсчитывать таймаут ожидания комманды от нуля в минусовом диапазоне. Так же до -127 и упором в это значение.
Переменные bt_result и bt_cnt содержат в себе текущий буффер нажатий комманды и количество нажатий соответственно.
Мы в любой момент можем их прочитать и, например если уже набрана однозначная комманда, дострочно прервать ее ожидание и выполнить.
Далее идет ступенчатый исключающий if(я не знаю, как его назвать правильно). Конструкция if-then-else-if.
Ее прелесть в том, что если срабатывает условие, дальнейшие условия уже не проверяются.
В принципе это аналог switch, но if позволяет загонять довольно сложные условия на проверку. Switch работает только с перечислимыми типами данных.
Условие первое. Проверяем, удерживается ли сейчас кнопка в нажатом состоянии(Pressed). Если да, инкрементируем счетчик длины нажатия.
Если нет, переходим к следующей проверке, которая сразу и однозначно нам говорит, что кнопку только что отпустили.
Простое условие (bt_time>0), а говорит о многом сразу.
Уже чуете, в чем прелесть таких конструкций? Каждое условие само себя исключает из цикла обработки.
По данному условию обрабатываем отжатие кнопки. Инкрементим счетчик нажатий, и если нажатие было длинным, поднимаем соответствующий бит в нашем буффере.
Здесь же проверяем, достигли ли мы максимума нажатий или набрана ли уже однозначная комманда.
Если да, пытаемся обработать комманду и сбрасываем состояние.
Следующее условие (bt_cnt>0 && bt_time>-release_timeout) занимается счетчиком таймаута после последнего отпускания кнопки.
Кроме этого условия мы так же железно знаем, что кнопка сейчас не нажата. Если нажата, мы в это условие просто не сможем попасть.
Ну и последнее условие выполнится, когда наступит таймаут ожидания комманды.
В нем мы тоже пытаемся обработать комманду и сбрасываем состояние.
Еще один прикол данного метода, что мы в любой момент можем снять текущий набранный юзером паттерн.
И например отобразить его на светодиодной линейке, как в основной статье. А текущее ожидаемое нажатие можем отображать на той же линейке мигающим диодом, соотвествующим по индексу текущему значению переменной bt_cnt. Отображение можно повесить на отдельную асинхронную задачу - рисуем паттерн и постоянно мигаем диодом с индексом bt_cnt.
Мне кажется это было бы нагляднее. Например наберем морзянкой ".-..-"(точка-тире-точка-точка-тире):
- Мигает первый диод.
- Жмем коротко на кнопку.
- Первый диод тухнет, второй начинает мигать.
- Жмем длинно.
- Второй загорается постоянно, мигает третий.
- Жмем два раза коротко.
- Третий и четвертый не горят, мигает пятый.
- Жмем длинно.
- Пятый горит, шестой мигает.
Почему после выполнения программы Reset происходит не так как при аппаратном Reset
Автор AksЯзык: Ассемблер AVR
Опубликовано 1 мая 2012 года в 11:35
Ожидаем нескольких сигналов 'w' говорящих о пререполнении емкости ..., потом на сотовом телефоне в определенной последовательности нажмутся кнопки с задержками по времени, а потом надо просто перезагрузит МК. А вот тут то чудеса. Он перезагрузится, очистится, но никогда не остановится.
main.c
Автор Pika4uЯзык:
Опубликовано 14 апреля 2012 года в 17:43
void func1(){if(Button()==3) ...
USB-FT232RL-Atmega8515
Автор NICЯзык: Ассемблер AVR
Опубликовано 29 февраля 2012 года в 11:13
Микросхемка FT232RL передает значение на AtMega8515. Но микроконтроллер не принимает или не обрабатывает полученные значения. У меня предположение, что все из-за инициализации. Помогите понять.
Светосинхронизатор
Автор A_ndrejЯзык: Ассемблер AVR
Опубликовано 16 февраля 2012 года в 11:35
Светосинхронизатор замеряет время от первого предвспыха вспышки фотоаппарата до последнего. И при следуещем пыхе ведущей вспышки, контролер будет включать ведомую вспышку точно тогда когда нужно.
микрогистерезис
Автор ingorЯзык: Ассемблер AVR
Опубликовано 6 февраля 2012 года в 10:36
микрогистерезис
Инициализация DRF7020D20
Автор ElectronikЯзык: C++
Опубликовано 20 декабря 2011 года в 11:36
Инициализация DRF7020D20
аналог буфера для приёмника на Си
Автор Arcanum7Язык: C++
Опубликовано 16 декабря 2011 года в 20:38
примерный вариант
uart_snd
Автор FatalistЯзык: Ассемблер AVR
Опубликовано 7 декабря 2011 года в 01:51
посылка в уарт данных
| 1234567 | Следующая страница > |


