.def temp=R25
;...................
T1OVF:
in r16, PIND ; считываем порт d
andi r16, 0b00110110 ;обнуляем лишние pd
cpi r16, 0 ;если r16=0, тоесть ни одна кнопка не нажата, выход
breq _return_ ;иначе переход на сравнение со старым кодом кнопки
cp r16, keyold ;сравнение со старым кодом кнопки
mov keyold, r16 ;запись в keyold r16
brne A1 ;переход если не совпадает, проверяем время кнопки
inc TmKey
cpi TmKey, 50
brsh Long ;переход если больше 1 сек
reti
Long:
sbr temp, 0
subi TmKey, 50
..........
reti
A1:
cpi TmKey, 5
brsh Short ;переход если больше равно 0.1 сек - короткое нажатие
rjmp Drebezg ; иначе обрабативаем дребезг
.............
;Обрабатывать всякого рода нажатие нужно по этих метках:
Short:
sbrc temp, 0
rjmp _return_
..........
rjmp _return_
Drebezg:
sbrc temp, 0
rjmp _return_
..........
rjmp _return_
_return_:
cbr temp, 0
clr TmKey
reti
Опять начались голюцинации со вторым таймером T0 , на кнопки нажимаешь писчит , но немогу провкрить регулировку от нажатия ,так как нормально не работает второй таймер ????
ни пойму что мешает нормальной работе второго таймера
Значит, должны вызиваться обработчики KPlus, KMinus при нажатии на соответственну кнопку, да? И тебе нужно ище при етом распознать короткое или длинное нажатия, да?
Если да, то вот код:
.include "tn2313def.inc"
;определения регистров
;основной цикл програми
_main_:
; sbis PIND,plus ;а может надо sbic? ,если при нажатии идет 1
; rcall KPlus ;
; sbis PIND,minus ;и тут тоже
; rcall KMinus ;кстати, етих 4-х строк ненужно, поскольку ты
;распознаеш нажатую кнопку в DescryButton
;(распознать кнопку)
in keynew, pind
andi keynew, 0b00110000
cpi keynew, 0b00010000
breq beep ;тут стояло rjmp, поетому вне зависимости от сравнения
;переход был всегда, всегда было beep
cpi keynew ,0b00100000
breq beep ;и тут тоже
;то, что тут было, можна реализовать как отдельную функцию, которая
;вызивается в обработчиках короткого или длинного нажатия
;иначе KPlus и KMinus будут срабатывать очень много раз
rjmp _main_
DescryButton:
cpi key, 0b00010000
breq KPlus
cpi key, 0b00100000
breq KMinus
ret
T1_OVF:
in keynew, PIND ; ñ÷èòûâàåì ïîðò d
andi keynew, 0b00110000 ;îáíóëÿåì ëèøíèå pd
cpi keyold, 0
breq _return_
cp keynew, keyold
mov key, keyold ;чтоб потом можно было распознать
brne A1
inc TmKey
cpi TmKey, 50
brsh Long
rjmp _end
Long:
sbr temp, 0
subi TmKey, 50
; .............
rjmp _end
A1:
cpi TmKey, 5
brsh Short
rjmp Drebezg
Short:
sbrc temp, 0
rjmp _return_
rjmp DescryButton
;..........
rjmp _return_
Drebezg:
sbrc temp, 0
rjmp _return_
;..........
rjmp _return_
_return_:
cbr temp, 0
clr TmKey
_end:
mov keyold, keynew ;çàïèñü â keyold keynew
reti
KPlus:
;.............
ret
KMinus:
;.............
ret
Я не совсем понял четам у вас с кнопками но понялчто с задержками какая то фигня Я сталкивался с фигнёй с задержками. Прерывание по совпадению происходило у меня гораздо рань ше чем надо. Дык вот я сделал прерывание по переполнению записав в счётный регистр нужное число
.equ minus = PD4 ;
.equ plus = PD5 ;
; sbis PIND,plus ;а может надо sbic? ,если при нажатии идет 1
; rcall KPlus ;
; sbis PIND,minus ;и тут тоже
; rcall KMinus ;кстати, етих 4-х строк ненужно, поскольку ты
ты обсолютно прав , они впринципи не нужны я эти строчки написал как начинающий для проверки на нажатие ,да действительно все настолько быстро срабатывало ,вот поэтому я решил заморочится длинным и коротким нажатием ?????
sbis PIND,plus ;а может надо sbic? ,если при нажатии идет 1
если я ничего не путаю то при нажатии 0, так как вход подключен через резистор 10 ком а сами кнопки замыкают на минус ,если я не ошибаюсь то на входе все время 1 , а при нажатии 0 ????????
in keynew, pind
andi keynew, 0b00110000
cpi keynew, 0b00010000
breq beep ;тут стояло rjmp, поетому вне зависимости от сравнения
;переход был всегда, всегда было beep
cpi keynew ,0b00100000
breq beep ;и тут тоже
Это я пробывал очередной вариант опроса кнопок но через
in r16, pind как в таймере
помнишь я писал
попробывал в основном цикле такой вариант чтобы просто от нажатия пикало ,то же херь какая то получилась ,после нажатия таймер T1 опять заглючило ,спустя 2-3 сек опять раздался пик и T1 начинает работать нормально ,ума не приложу в чем дело ????
походу это оттого что я использовал rjmp вместо breq !!!!!
кстати, раньше я скинул работающий код, в каком длинное нажатие обрабатывается после отпускания, а не каждую секунду
ето не такой уж большой недостаток. Так зачем же вам мучиться, интересно?
уважаемый Петро я хотел сделать чтобы при нажатии на кнопку меньше 1 сек это было короткое нажатие а при больше 1 сек это длительное ,причем при коротком нажатие ,сразу обрабатывалась
бы нажатие ,а не при отпускании кнопки !!!!
Пример:
1.нажали и отпустили в течении 1 сек сработало KPlus или KMinus
2.нажали и держим более 1сек срабатывает KPlus или KMinus через
как бы задержку ,т.е пока держим нажатым кнопку через задержку вызывается KPlus или KMinus.
попробуйте вот что: скачайте исходник к моему термостату, "который меньше, чем не бывает" и посмотрите в него. я понимаю, что вы на асме пишите, а я на Си, но у меня очень подробные комментарии в тексте, и именно их я рекомендую почитать: вам станет понятен алгоритм поведения, а уж потом его реализовать на ассемблере - дело техники.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
AI_Disable писал(а):Я делал так: в основном цикле проверял, нажата ли кнопка, если да, то делаем ++ переменной. Если кнопка не нажата и переменная больше нуля, сравниваем её с неким значением(которое зависит от скорости выполнения основного цикла и подбирается экспериментально). Если переменная меньше - это кратковременно нажатие, если больше - длительное. После, сбрасываем переменную.
На мой взгляд, это самый рациональный и простой способ, т.к. не пожирает драгоценный таймер на такую ерунду и работает без задержек в цикле.
ЗЫ: единственный минус - если основной цикл повторяется очень быстро (тысячи раз в секунду), то тогда переменная начнёт жрать память, неподобающим образом.
Тут уж выбирайте, что вам важнее: таймер или 2-4 байта памяти.
А нельзя дробные использовать? или это тоже лишнюю память тратит?
MTF писал(а):уважаемый Петро я хотел сделать чтобы при нажатии на кнопку меньше 1 сек это было короткое нажатие а при больше 1 сек это длительное ,причем при коротком нажатие ,сразу обрабатывалась
бы нажатие ,а не при отпускании кнопки !!!!
Пример:
1.нажали и отпустили в течении 1 сек сработало KPlus или KMinus
2.нажали и держим более 1сек срабатывает KPlus или KMinus через
как бы задержку ,т.е пока держим нажатым кнопку через задержку вызывается KPlus или KMinus.
Чтоб сработало при нажатии нужно просто сделать проверку переменной, в которой хранится время нажатия и прерывание цикла проверки для выполнения кода обработки LONG, когда превышено время нажатия.
Я обычно для предотвращения дребезга использую интервал времени 200мСек. Чтоб сделать селектор по времени нажатия нужно к счетчику 200мСек прилепить еще один счетчик до пяти. Алгоритм следующий:
1. Проверяем нажатие клавиши.
2. Если нажата, то инициализируем счетчик от дребезга и счетчик селектор. Взводим флажек нажатия кнопки.
3. После отсчета 200мСек проверяем повторно: нажата кнопка или нет? Если нет то сбрасываем флажек нажатия и делаем вывод - дребезг. Если нажата, то
4. Инкрементируем таймер селектор. инициализируем таймер дребезга.
5. После отсчета 200мСек проверяем повторно: нажата кнопка или нет? Если нет, проверяем таймер селектор и если там не ноль, то на обработку короткого нажатия. Если нажата, то инкркментируем таймер селектор и далее по циклу.
6. Если после очередного отсчета и проверки на нажатие кнопка нажата втечении интервала 1сек и счетчик селектор инкрементировался до 5, переходим на обработку длинного нажатия кнопки.