Способов как минимум два:
1) ветвление по состоянию бита (sbic, sbis)
2) логическое "И" содержимого порта (регистра) с константой (00010000) с последующим сравнением с константой (cpi), либо с содержимым другого регистра с ветвлением (cpse).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Сравнивать надо с нулем - это сравнение происходит сразу в момент применения функции "И". Если там не будет "1" в порту, то результат функции "И" будет нулевой, иначе - не нулевой.
Спасибо большое, со всем разобрался!
Клацает как я и хотел!
Теперь подобный вопрос. Возникает чувство что начинаю изобретать велосипед.
Как проверить состояние ножки контроллера по спадающему или восходящему фронту импульса?(И при этом не использовать таймеры, хотя они как раз и для таких случаев предназначены)
Т.е. нажимаем на кнопочку, действие выполняется, и оно опять не выполнится пока мы её не отпустим и обратно не нажмем.
Представляется опять такой алгоритм с использованием команд 8-10 и 3х регистров как минимум )
Или, скоре всего, без таймера и прерываний здесь совсем не обойтись.
Для этого нужно хранить предыдущее состояние кнопки где-то.
Тогда у нас в момент проверки возможны только 4 состояния: нажата-отпущена, отпущена-отпущена, отпущена-нажата и нажата-нажата. Соответственно, нас интересуют 1 и 3-е состояние.
После проверки, состояние кнопки просто скопировать в предыдущее, независимо от состояния.
Если предыдущее состояние хранить в том же бите что и регистр порта, можно будет использовать XOR и последующий AND чтобы выявить моменты 1 и 3-го состояния, и передать управление на подпрограмму которая определяет что делать по нажатию кнопки или по отпусканию.
Можно то же самое сделать используя прерывания. Разрешать их не обязательно - можно настроить порт на прерывание по изменению уровня и смотреть признак прерывания, хоть оно и будет запрещено - признак все равно работает, главное не забывать его сбрасывать. И тут так же надо иметь в виду, что между установкой этого признака и моментом считывания состояния порта с целью определить направление нажатия проходит некоторое время, за которое уровень на выводе контроллера вполне может изменится. Тогда возникает ситуация было "0", возник признак прерывания считываешь порт, а там снова "0". Имеем вместо регистрации реального события 0->1 подразумеваем что возникло событие 1->0 так как предыдущее значение нигде не сохраняется для анализа, а если и сохраняется то смысл городить огород с прерываниями.
2 и 4 состояние можно использовать для реализации автоповтора. Когда видим в результате проверки 4-е состояние, декрементируем счетчик и когда он доходит до нуля выполняем нужное действие как будто по 3-му или 1-му состоянию. И соответственно в 1 и 3-м состоянии устанавливаем этот счетчик некоторой константой - чем меньше число тем чаще повтор.
что-то немного запутался
надо учесть что все это во время работы генерит динамичесую индикацию
Если кратко говорить то в результате должен получиться счетчик на 4 разряда
Display:
clr r16
in r16,PinD; считываем порт в R16
mov r3,r16, записываем R16 в R3
sbrc r16,4; проверяем 5-ю ножку на высокий уровень
rcall InfCycle; если он там есть, то переходим на InfCycle
uu:
ldi R17,0b00001110 ; Включаем катод первого
out PortD,R17
mov R22,r23; пересылаем из регистра первого разряда в регистр адреса декодера
rcall Decoder ; конвертируем в бинарный код
out PortB,R17 ; выводим на порт
rcall Delay1 ; задержка
Далее все также с еще 3-мя разрядами
rjmp display
Decoder:
ldi ZL,Low(DcMatrix*2)
ldi ZH,High(DcMatrix*2)
ldi R18,0
;ldi R22,1
add ZL,R22
adc ZH,R18
lpm
mov R17,r0
ret
InfCycle:
clr r16
in r16,PinD
eor r16,r3
sbrs r16,4
rjmp big
clr r3
ret
big:
sts digit,r23
inc r23
cpi r23,10
breq M
ret
M:
clr r23
ret
DcMatrix:
; hgfedcba hgfedcba
.db 0b00111111,0b00000110 ;0,1
.db 0b01011011,0b01001111 ;2,3
.db 0b01100110,0b01101101 ;4,5
.db 0b01111101,0b00000111 ;6,7
.db 0b01111111,0b01101111 ;8,9
Delay1: ; задержка
ldi R20,20
ldi R21,11
d11:
dec R20
brne d11
dec R21
brne d11
ret
Gudd-Head писал(а):Нет смысла обнулять регистр перед закидыванием в него значения.
R16м я там настраиваю порты. НО там еще много бредятины. Которая вылезла в процессе экспериментов
А потом не была убрана так как вроде не мешала
вопрос собственно по этим строчкам
раз:
in r16,PinD; считываем порт в R16
mov r3,r16, записываем R16 в R3
sbrc r16,4; проверяем 5-ю ножку на высокий уровень
rcall InfCycle; если он там есть, то переходим на InfCycle
и два:
in r16,PinD; считыаем портD в r16
eor r16,r3 ; исключющее или между r3 и r16
sbrs r16,4 ; проверяем 4-й бит
rjmp big ; если не установлен то переходим на подпрограмму увеличения адреса масиива
clr r3
ret
В каком коде, в том то и дело, что после команды SLEEP программа не двигается, из режима IDLE выходит и прога дальше работает, а после POWER-DOWN стоит на месте.
Да, да. Она все-таки есть в приведенном вначале коде, и именно из-за невнимательного чтения даташита... Но ведь не факт, что именно он выполняется в качестве инициализации, ведь программа вначале прыгает на метку reset, а вот код, который с нее начинается как раз и не выложен.
Последний раз редактировалось Engineer_Keen Пн окт 08, 2012 10:58:19, всего редактировалось 1 раз.
Engineer_Keen писал(а):программа вначале прыгает на метку reset, а вот код, который с нее начинается как раз и не выложен.
Таки да, лол.
А ещё reti в векторе прерываний, хотя у 16-й Меги на каждое прерывание отведено по 2 слова (4 байта). Т.е. на самом деле всё выглядит так:
Gudd-Head писал(а):
А ещё reti в векторе прерываний, хотя у 16-й Меги на каждое прерывание отведено по 2 слова (4 байта). Т.е. на самом деле всё выглядит так:
.org $000
jmp RESET ; External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
.org $002
jmp EXT_INT0 ; INT0 Внешнее прерывание 0
reti ; INT1 Внешнее прерывание 1
reti ;
reti ; TIMER2 COMP Совпадение таймера/счетчика Т2
reti ;
...
По большому счету это не важно, процессор все равно попадает на команду RETI, тем более перед ним стоит команда абсолютного перехода, которая занимает свои четыре байта и смещает команду на свой адрес.
По ресету ничего сверхестественного, установка вершины стека и обнуление регистров РОН