Я уже ковырялся с обтроном SG-2BC и самодельным обтроном из ИК-светодиода и фототранзистора (оба китайского производства, не могу сказать название), оба раза кончились усилительным каскадом на BC547C =) Только обтрон работал на режиме срабатывания нуля на ножке, а вот самодельная штука реагировала только при установке прерывания по спадающему фронту =) Ей, похоже, надо ещё один каскад делать
Как раз этим и занимаюсь - есть тройной семисегментный индикатор, который уже умеет считать 000-999-000, вот хочу ему сделать друга в виде оптопары, чтобы не скучно было Сорри за лирическое отступление
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Сделайте по описанному мной алгоритму и не недо никаких оптопар и конденсаторов. Вам главное дребезг пропустить, а потом проверить кнопку и не повторить проверку лишний раз (признак нового нажатия может быть только после отпускания кнопки, либо по истечению какогото времени (автоповтор)). Вот пример на асм. Спойлер
;==================== ; Обработчик прерывания по нажатию кнопки ;====================
INT_Button:
ldi tmp0,($FF-$61) ;Загружаем константу во временный регистр (счетчик переполнится через 100мС) out TCNT0,tmp0 ;Записываем ее в регистр счетчико Таймера0 in tmp0,TIMSK ;Считываем регистр маски прерываний sbr tmp0,0b00000001 ;Устанавливаем бит TOIE0 (разрешение прерывания от Таймера0) out TIMSK,tmp0 ;Записываем измененные данные в регистр маски прерываний
in tmp0,TIFR ;Считывае регистр флагов прерываний cbr tmp0,0b00000001 ;Сбрасываем бит TOV0 (флаг прерывания от переполнения регистра счетчика Таймера0) com tmp0 ;Инвертируем регистр out TIFR,tmp0 ;Записываем в регистр флагов прерываний
reti ;Выход из прерывания
;=================== ; Обработчик прерывания по переполнению Таймера0 ;=================== OVF0:
in tmp0,TIMSK ;Считывае регистр флагов прерываний cbr tmp0,0b00000001 ;Сбрасываем бит TOIE0 (запрет прерывания от Таймера0) out TIMSK,tmp0 ;Записываем измененные данные в регистр маски прерываний
in tmp0,PIND ;Считываем сотояние выводов порта andi tmp0,0b00000011 ;Выделяем наши кнопки tst tmp0 ;Проверяем нажаты две кнопки brne NotTwoKey ;Две кнопки не нажаты переходим на проверку нажатия кнопок
В данном примере не кретично была кнопка отпущена или нет так как прерывание от кнопки произойдот только при низпадающем фронте, т.е. только при следующем нажатии.
Нельзя так делать еще и потому что задержка в прерывании - это жесточайшее ЗЛО.
На время прерывания программа останавливается в произвольном месте, например в момент переключения сегмента. и программа будет стоять 50мс при нажатии кнопки, неспособная что-либо сделать в принципе!
Самый простой и верный способ подавления дребезга - считывать кнопку только ОДИН раз в течение времени не менее 1мс(для геркона и 10мс для обычной кнопки). Каждое такое считывание сверяешь с предыдущим состоянием кнопки и у тебя сразу же будет дополнительная информация - ты будешь знать нажата ли кнопка только что, или её только что отпустили. Единственное действие дребезга на данный алгоритм - реальное состояние МОЖЕТ быть зафиксировано через время величиной не более чем один опрос от фактического момента нажатия. т.е. если опрос попал ровно на момент нажатия и его дребезга, то фактически нажатие может быть с вероятностью 50/50 зафиксировано либо в тот же момент, либо в следующий опрос. Но зафиксировано будет только один раз, что и нужно для антидребезга.
Прерывания и подавление дребезга через прерывание надо делать только когда нужна максимально быстрая реакция на нажатие кнопки. Но в данном случае по прерыванию надо 1) запретит прерывание от кнопки, 2) сбросить признак прерывания(а вдруг до запрета еще один импульс дребезга проскочил) 3) установить глобальную переменную сигнализирующую о факте нажатия кнопки 4) стартовать таймер, отмеряющий возможное время дребезга 5) в обработчике прерывания от таймера разрешить прерывание от кнопки и остановить таймер. Хотя можно несколько модифицировать алгоритм: прерывание от кнопки не запрещать - просто в прерывании от кнопки: 1) факт нажатия - игнорировать если есть признак игнорирования нажатия, 2) сбрасывать таймер, 3) запустить его(повторный запуск уже запущенного не помешает но позволит избавится от дополнительной проверки условия) и установить признак игнорирования нажатия(если он не установлен). По окончании выдержки таймером сбросить признак игнорирования нажатия и остановить таймер. В данном случае факт остановки таймера можно использовать как признак инверсный "признаку игнорирования нажатия", тогда и переменные лишние заводить не надо будет. Активен таймер - игнорируем нажатие в прерывании, остановлен - не игнорируем.
Этот алгоритм позволит не привязываться к параметрам кнопки, а адаптируется к длительности дребезга "на месте", надо только указать максимальное время между возможными импульсами дребезга. Можно задать около 1мс(для кнопки, оптрону можно на порядок меньше задать но тут лучше на практике выяснить т.к. и у оптронов бывает дребезг особенно открытых), а можно на практике выяснить - это повлияет на максимальную частоту с которой можно регистрировать нажатия.
Здравствуйте! Я хочу начать изучать микроконтроллеры потомучто на них можно сделать много всего интересного. Говорят, что этот язык просто изучаеться. Подскажите, с чего начать?
Сначала определись с контроллером, потом идешь на сайт производителя контроллера и ищешь там среду программирования что они предлагают, выбираешь язык и начинаешь учится. Потом приходит понимание нужности чего-то большего...
Для начала начни с ATMEGA8 или ATMEGA16 (которая будет доступней), AVR STUDIO 6 скачанной с офсайта(нужна простая регистрация в ходе получения ссылки на скачивание, статистику собирают что-ли?) и соответственно ассемблера. Есть конечно обучающие какие-то сайты и литература... но мозг и здравый смысл ничто не заменит. Не пытайся сначала писать программы, лучше начни с того как все это работает и почему. А так же желательно научится писать программы вообще, хоть на паскале или бейсике на большом компе. Без способностей составлять алгоритмы начинать программировать контроллеры - зря потраченное время и усилия специалиста по дальнейшему переучиванию.
п.с. имей в виду что язык легко изучается но очень сложно отучается(забывается).
Имеется зарезервированная ячейка оперативки на 4 байта:
Digit: .byte 4
Имеется макрося, внутри котрого есть относительный переход на некую метку:
... brne IC ...
Если я пишу код, в котором присутствует переменная Digit (sts, lds), и этот код размещается после метки IC, при компиляции получаю ошибку relative branch out of reach
Если код с переменной вставить до метки - всё компилируется правильно.
Что это за штука такая? Оо
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Точнее на -64...+63 машинных слова. количество команд может быть меньше.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Адово. А есть какая-то статейка, которая о таких подводных камнях рассказывает? Я не имею ввиду тех документацию или какой-то мануал на ассемблер. Именно обзорную статью
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.