Страница 1 из 3
ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 07:02:38
Uklunok
Набросал тут небольшой код. При нажатии кнопки, светодиод напротив загорается, при повторном нажатии на ту же самую кнопку светодиод тухнет. Начал придумывать код, но не знаю будет ли работать как надо (для stk500), т.к. проверить пока что нет возможности.
Ниже представлен кусок кода: по нажатию кнопки светодиод напротив загорится
Код: Выделить всё
.include "m16def.inc"
.def Delay =r17
.def Delay2 =r16
.def temp =r18
DDRA=0x00
DDRB=0xFF
LOOP:
IN temp,PINA
sbic PINA,0x00
OUT PORTB,temp
sbic PINA,0x01
OUT PORTB,temp
sbic PINA,0x02
OUT PORTB,temp
sbic PINA,0x03
OUT PORTB,temp
sbic PINA,0x04
OUT PORTB,temp
sbic PINA,0x05
OUT PORTB,temp
sbic PINA,0x06
OUT PORTB,temp
sbic PINA,0x07
OUT PORTB,temp
rjmp DLY
DLY:
dec Delay
brne DLY
dec Delay2
brne DLY
rjmp LOOP
не уверен что после отпускания кнопки светодиод всё ещё будет гореть. Остальную часть задания пока не рассматривал.
За ранее спасибо.
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 09:46:08
Engineer_Keen
Ну для начала:
1)
Это что такое?

Раз уж прога на ассемблере так и надо писать на ассемблере
Код: Выделить всё
LDI temp,0x00
OUT DDRA,temp
LDI temp,0xFF
OUT DDRB,temp
Ну или через макросы, чтобы покороче
Код: Выделить всё
;перед программой
.macro OUTI
LDI temp @1
OUT @0,temp
.endm
.cseg
;где-то в самой программе
OUTI DDRA,0x00
OUTI DDRB,0xFF
2) Стек не инициализирован. Он пока не нужен, а если потом понадобится?
3) rjmp DLY, и на следующей строчке метка DLY? Тогда уж RCALL DLY, а на следующей строчке RJMP LOOP (вот тут уже и стек используется)
4) Светодиоды гореть будут. Как только кнопки нажмут. И больше не погаснут, так как в программе указан просто вывод на порт нажатой кнопки, а нужно переключение.
5) Кстати, кусок кода после DLY это антидребезг?
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 11:30:19
Uklunok
ОК, спасибо. В ответ на ваши вопросы:
1. Я думал, что если ставится метка например тут "DLY", то в коде обязательно нужно указать переход на неё... Ну теперь буду знать, что команда перехода не обязательна.
2. Думаю, что стек не пригодиться... И вроде бы область стека уже имеется в памяти, поэтому достаточно обойтись командами пуш и поп, контроллер сделает всё сам.
3. DLY - это антидребезг (задержка), чтобы в регистр поместился именно тот бит, какая кнопка была нажата.
Я просто больше склонялся к тому, что светодиод будет гореть в момент нажатия кнопки, когда кнопку опустишь - потухнет.
Теперь вы меня прояснили и всё стало ясно. Завтра проверю на стенде и попытаюсь написать остальной кусок кода.
Ещё раз спасибо.!!!
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 12:03:23
Engineer_Keen
Uklunok писал(а):
1. Я думал, что если ставится метка например тут "DLY", то в коде обязательно нужно указать переход на неё... Ну теперь буду знать, что команда перехода не обязательна.
Метка это просто адрес, которому дали имя для удобства и наглядности программы.
Uklunok писал(а):
2. Думаю, что стек не пригодиться... И вроде бы область стека уже имеется в памяти, поэтому достаточно обойтись командами пуш и поп, контроллер сделает всё сам.
Ага, вот как-раз без инициализации стека он по командам PUSH и POP (а не только RCALL/RET) сделает неизвестно что, потому что после включения в регистрах указателя стека SPH:SPL может быть любое случайное число...
Uklunok писал(а):
Я просто больше склонялся к тому, что светодиод будет гореть в момент нажатия кнопки, когда кнопку опустишь - потухнет.
Тогда зачем такие сложности? Достаточно:
Код: Выделить всё
LOOP:
IN temp,PINA
OUT PORTB,TEMP
DLY:
...
...
RJMP LOOP
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 15:07:06
Uklunok
[/quote]
Тогда зачем такие сложности? Достаточно:
Код: Выделить всё
LOOP:
IN temp,PINA
OUT PORTB,TEMP
DLY:
...
...
RJMP LOOP
[/quote]
Бррррррр...

Эт Я так предположил, что программа будет работать именно так, как вы написали в этом примере. Повторюсь, на атмеге это моя первая программа, пишу её "вслепую", т.к. стенда под рукой нет, и эмулятора как Я понял не существует, вот... и не уверен будет ли работать код который Я написал, так как мне надо. А нужно, чтобы после отпускания кнопки светодиод продолжал светиться)))
Исходя из выше сказанного вами написанного: лучше стек организовывать самому чтоли??? Т.е. выделить сегмент памяти и туда закидывать сохраненную информацию??? И как его инициализировать?
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 15:13:56
Fasterpast
и эмулятора как Я понял не существует
AVRstudio? Proteus?
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 16:26:04
Engineer_Keen
Uklunok писал(а):
Исходя из выше сказанного вами написанного: лучше стек организовывать самому чтоли??? Т.е. выделить сегмент памяти и туда закидывать сохраненную информацию??? И как его инициализировать?
Зачем по-вашему в AVR регистры указателя стека? Просто пишете в самом старте программы
Код: Выделить всё
LDI R16,Low(RamEnd)
OUT SPL,R16
LDI R16,High(RamEnd)
OUT SPH,R16
и все, стек инициализирован. Он будет расти вниз от конца RAM (константа RamEnd), и можете спокойно пользоваться командами PUSH/POP/CALL/RET/RETI...
Вы бы даташит на контроллер почитали, особенно раздел AVR CPU Core - Stack Pointer.
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Пн фев 28, 2011 19:45:58
Much functional
по нажатию кнопки светодиод напротив загорится
напротив относительно вас, или преподавателя?
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Вт мар 01, 2011 11:39:50
Uklunok
Получилось зажечь светодиоды - на стенде проверил, вот код:
Код: Выделить всё
.include "m16def.inc"
.def Delay =r17
.def Delay2 =r16
.def temp =r18
LDI temp,0xFF
OUT DDRB,temp
LDI temp,0x00
OUT DDRA,temp
LOOP:
IN temp,PINA
sbis PINA,0x00
OUT PORTB,temp
sbis PINA,0x01
OUT PORTB,temp
sbis PINA,0x02
OUT PORTB,temp
sbis PINA,0x03
OUT PORTB,temp
sbis PINA,0x04
OUT PORTB,temp
sbis PINA,0x05
OUT PORTB,temp
sbis PINA,0x06
OUT PORTB,temp
sbis PINA,0x07
OUT PORTB,temp
rjmp LOOP
Но возникли вопросы:
1). Когда программа залита (ещё ничего не жал), все светодиоды сразу горят, это наверно из-за того что порт Б настроен на выход. Но я так не хочу

Реально сделать, чтобы по умолчанию все светодиоды не горели???
2). Кусок кода с меткой LOOP, получается зацикливается, командой rjmp LOOP. Если rjmp LOOP убрать, всеровно работает. Какой от него тогда здесь смысл???
3). Немогу додуматься каким образом потушить светодиод по нажатию кнопки, 3 часа провозился так ничего не придумал...

Re: ПОДСВЕТКА, проверьте ))
Добавлено: Вт мар 01, 2011 11:52:59
O-LED
3). Немогу додуматься каким образом потушить светодиод по нажатию кнопки, 3 часа провозился так ничего не придумал...

чтоб потушить светодиод, нужно снять с него напряжение. Вы за 3 часа не придумали как снять напряжение с ножки контроллера?
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Вт мар 01, 2011 12:01:05
Engineer_Keen
1) Так в начале программы не написано должны они гореть или нет. Нужно при инициализации записать в PORTB ноль
2) Если убрать RJMP LOOP в конце, программа не будет работать корректно. У вас происходит либо постоянный сброс либо циклический перебор всей программной памяти, а так как ее не так много, кажется что программа просто нормально работает. Ну представьте что случится, если после отсутствующей команды RJMP LOOP будет находится какая-нибудь подпрограмма.
3) Нужно по нажатию кнопки сначала проверять состояние конкретного бита PORTB, и уже на основываясь на этой информации либо устанавливать его, либо сбрасывать. Кстати, если просто проверять, что какая-либо кнопка нажата, то у вас соответствующий светодиод будет мигать с частотой, заданной подпрограммой антидребезга. Чтобы этого избежать нужно еще проверять что эту кнопку отпускали...
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Вт мар 01, 2011 13:59:00
ChipKiller
Uklunok писал(а):Код: Выделить всё
LOOP:
IN temp,PINA
sbis PINA,0x00
OUT PORTB,temp
sbis PINA,0x01
OUT PORTB,temp
sbis PINA,0x02
OUT PORTB,temp
sbis PINA,0x03
OUT PORTB,temp
sbis PINA,0x04
OUT PORTB,temp
sbis PINA,0x05
OUT PORTB,temp
sbis PINA,0x06
OUT PORTB,temp
sbis PINA,0x07
OUT PORTB,temp
rjmp LOOP
... для начала разберитесь с логикой работы, не нужно писать "20 строк", там где можно обойтись 2-мя.
Код: Выделить всё
LOOP:
IN temp,PINA
OUT PORTB,temp
rcall Delay
rjmp LOOP
... оформите Delay в виде процедуры, в которой помимо задержки содержится обработка нажатия/отпускания кнопки.
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Вт мар 01, 2011 22:59:06
AndyWorld
Вот пример включения 3х диодов. Нажали включился 1-й,еще - 2-й, и еще 3-й. На четвертое нажатие гаснут все. И все по новой.
;=====
;Объявления
.def temp =r16
.def delay1 =r17
.def delay2 =r18
.def delay3 =r19
;=====
;Начало программы
rjmp Init
;==========
; Подпрограммы
; Устранение дребезга кнопки
; Задержка 0.2 с формируется из расчета кварц 4Мгц убиваем 160000 тактов
; соответственно 160000=$027100
; 0,1s = 80000=$013880
; 0,2s = 160000=$027100
; 0,3s = 240000=$03а980
debounce:
ldi delay1,0x00
ldi delay2,0x71
ldi delay3,0x02
loop:
subi delay1,1
sbci delay2,0
sbci delay3,0
brcc loop
ret
;=====
Init:
ldi temp, 0b011111 ;Определяем выходы порта В
out DDRB,temp
clr temp ;Очищаем порты
out PortB,temp
;=====
;Основное тело программы
Start:
sbis PinB,5 ;проверяем нажата ли кнопка если да то переходим к задержке
rcall debounce
;если нет то переходим дальше
ReleaseWait:
sbis PinB,5 ;проверяем нажата ли кнопка если да то переходим к
rjmp ReleaseWait ; началу цикла
rcall debounce ; если да то ждем и переходим
rjmp Led0 ;к проверке светодиодов
Led0: ;===== Контроль светодиодов ======
sbis PortB,0 ; Проверяем диод, если он не горит
rjmp Led0_on ; то переходим к циклу его включения
rjmp Led1 ; если он горит то переходим ко второму диоду
Led0_on:
sbi PortB,0 ;включаем диод и возвращаемся в начало
rjmp Start
Led1:
sbis PortB,1 ; Проверяем диод, если он не горит
rjmp Led1_on ; то переходим к циклу его включения
rjmp Led2 ; если он горит то переходим ко третьему диоду
Led1_on:
sbi PortB,1 ;включаем диод и возвращаемся в начало
rjmp Start
Led2:
sbis PortB,2 ; Проверяем диод, если он не горит
rjmp Led2_on ; то переходим к циклу его включения
rjmp Led_off ; если он горит то горят уже все 3 диода, значит пора выключать
Led2_on:
sbi PortB,2 ;включаем диод и возвращаемся в начало
rjmp Start
Led_off:
clr temp ; Очищаем весь порт
out PortB, temp ; и возвращаемся на начало проверки кнопок
rjmp Start
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Ср мар 02, 2011 12:13:48
Uklunok
AndyWorld писал(а):Вот пример включения 3х диодов. Нажали включился 1-й,еще - 2-й, и еще 3-й. На четвертое нажатие гаснут все. И все по новой.
;=====
;Объявления
.def temp =r16
.def delay1 =r17
.def delay2 =r18
.def delay3 =r19
;=====
;Начало программы
rjmp Init
;==========
; Подпрограммы
; Устранение дребезга кнопки
; Задержка 0.2 с формируется из расчета кварц 4Мгц убиваем 160000 тактов
; соответственно 160000=$027100
; 0,1s = 80000=$013880
; 0,2s = 160000=$027100
; 0,3s = 240000=$03а980
debounce:
ldi delay1,0x00
ldi delay2,0x71
ldi delay3,0x02
loop:
subi delay1,1
sbci delay2,0
sbci delay3,0
brcc loop
ret
;=====
Init:
ldi temp, 0b011111 ;Определяем выходы порта В
out DDRB,temp
clr temp ;Очищаем порты
out PortB,temp
;=====
;Основное тело программы
Start:
sbis PinB,5 ;проверяем нажата ли кнопка если да то переходим к задержке
rcall debounce
;если нет то переходим дальше
ReleaseWait:
sbis PinB,5 ;проверяем нажата ли кнопка если да то переходим к
rjmp ReleaseWait ; началу цикла
rcall debounce ; если да то ждем и переходим
rjmp Led0 ;к проверке светодиодов
Led0: ;===== Контроль светодиодов ======
sbis PortB,0 ; Проверяем диод, если он не горит
rjmp Led0_on ; то переходим к циклу его включения
rjmp Led1 ; если он горит то переходим ко второму диоду
Led0_on:
sbi PortB,0 ;включаем диод и возвращаемся в начало
rjmp Start
Led1:
sbis PortB,1 ; Проверяем диод, если он не горит
rjmp Led1_on ; то переходим к циклу его включения
rjmp Led2 ; если он горит то переходим ко третьему диоду
Led1_on:
sbi PortB,1 ;включаем диод и возвращаемся в начало
rjmp Start
Led2:
sbis PortB,2 ; Проверяем диод, если он не горит
rjmp Led2_on ; то переходим к циклу его включения
rjmp Led_off ; если он горит то горят уже все 3 диода, значит пора выключать
Led2_on:
sbi PortB,2 ;включаем диод и возвращаемся в начало
rjmp Start
Led_off:
clr temp ; Очищаем весь порт
out PortB, temp ; и возвращаемся на начало проверки кнопок
rjmp Start
Чтот мне кажется Я маленько не понял. Где инициализация и настройка потров? Я тут вижу только порт В, или он что, двунаправленый чтоли??? Где команда in, для получения инфы из входного порта?
И что-то мне кажется Я вообще недогоняю, чтобы диод постоянно горел, нужно команду out поместить в цикл... А то он будет гореть только в момент нажатия кнопки.
Вопрос: Например Я нажал 1-ю кнопку, пока Я её удерживаю в нажатом состоянии информация записывается в регистр temp по такой команде: in temp,PINA. Кнопку отпускаю - и что будет с регистром??? Туда поступит информация, что кнопка отжата???, т.е. регистр обнулится?
Спасибо за понимание)))
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Ср мар 02, 2011 13:21:57
Engineer_Keen
И самое интересное, где инициализация стека? Он же заглючит после первого же RCALLа...
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Ср мар 02, 2011 20:02:15
AndyWorld
Это мой старый проект на Тини11. Поэтому и не понятно что к чему. Нарисуй схему, что и как должно быть.
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Чт мар 03, 2011 13:07:17
Uklunok
Короче написал, что надо было:
Код: Выделить всё
.include "m16def.inc"
.def temp =r17
.def temp2 =r18
.def temp3 =r19
.def a1 =r20
.def a2 =r21
.def a3 =r22
.def a4 =r23
.def a5 =r24
.def a6 =r25
.def a7 =r26
.def a8 =r27
.def Delay =r29
.def Delay2 =r30
.def Delay3 =r31
LDI temp2,0xFF
OUT DDRB,temp2
ldi temp2,0b11111111
ldi a1,0b00000001
ldi a2,0b00000010
ldi a3,0b00000100
ldi a4,0b00001000
ldi a5,0b00010000
ldi a6,0b00100000
ldi a7,0b01000000
ldi a8,0b10000000
out PORTB, temp2
BEGIN:
ldi Delay3,0b00000010
DLY:
dec Delay
brne DLY
dec Delay2
brne DLY
dec Delay3
brne DLY
in temp,PINA
andi temp, 0b00000001
cpi temp, 0b00000001
breq INIT1
EOR temp2,a1
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT1:
in temp,PINA
andi temp, 0b00000010
cpi temp, 0b00000010
breq INIT2
EOR temp2,a2
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT2:
in temp,PINA
andi temp, 0b00000100
cpi temp, 0b00000100
breq INIT3
EOR temp2,a3
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT3:
in temp,PINA
andi temp, 0b00001000
cpi temp, 0b00001000
breq INIT4
EOR temp2,a4
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT4:
in temp,PINA
andi temp, 0b00010000
cpi temp, 0b00010000
breq INIT5
EOR temp2,a5
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT5:
in temp,PINA
andi temp, 0b00100000
cpi temp, 0b00100000
breq INIT6
EOR temp2,a6
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT6:
in temp,PINA
andi temp, 0b01000000
cpi temp, 0b01000000
breq INIT7
EOR temp2,a7
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT7:
in temp,PINA
andi temp, 0b10000000
cpi temp, 0b10000000
breq INIT8
EOR temp2,a8
OUT PORTB,temp2
in temp,PINA
rjmp TRAP
INIT8:
rjmp BEGIN
TRAP:
in temp3,PINA
cp temp,temp3
breq TRAP
rjmp BEGIN
Кому ни лень, или может интересно будет - посмотрите, может код можно компактнее сделать.
Да и на счёт задержки ещё стоит подумать (DLY)... Тут просто время подогнал под удобное удерживание клавиши, но какая длительность не знаю. А вообще антидребезг делается так: сравнивается два значения - после нажатия кнопки и перед тем как отпустить, если они окажутся одинаковыми, то антидребезг удался...
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Чт мар 03, 2011 13:34:42
ARV
Код: Выделить всё
.org 0
ldi r16, 255
out PORTA, r16 ; подтяжки на пины кнопок
out DDRB, r16 ; порт для выхода на светодиоды
loop:
in r0, PINA
eor r0, r16 ; получили единички там, где нажата кнопка
in r1, PORTB
eor r1, r0
out PORTB, r1 ; инвертировали состояние светодиода, соответствующего кнопке
wait: ; ждем, пока все кнопки будут отпущены
in r0, PINA
eor r0, r16
brne wait
rjmp loop
по-моему, как-то так... если я еще не совсем ассемблер забыл

дребезг не давится

Re: ПОДСВЕТКА, проверьте ))
Добавлено: Чт мар 03, 2011 14:32:20
Engineer_Keen
А так с антидребезгом в виде задержки.
Код: Выделить всё
.include "m16def.inc"
.macro OUTI
LDI R16,@1
OUT @0,R16
.endm
.macro DelayMS
LDI R16,@0
RCALL DELAY
.endm
.def LastKey=R20
.cseg
; RJMP START
;.org 0x0015
START:
OUTI SPL,low(ramend)
OUTI SPH,high(ramend);стек
OUTI DDRB,0xFF ;B на выход
OUTI PORTB,0x00 ;и его в 0
OUTI DDRA,0x00 ;A на вход
OUTI PORTA,0xFF ;и ему подтяжку
LOOP: IN R16,PINA ;читаем À
COM R16 ;инвертируем (если кнопки на землю)
EOR LASTKEY,R16 ;проверка изменения состояния кнопок
AND LASTKEY,R16 ;и что измененная кнопка нажата
IN R17,PORTB ;читаем старое значение на выходе
EOR R17,LASTKEY ;инвертируем соответствующий выход
OUT PORTB,R17 ;вывод в порт
MOV LASTKEY,R16 ;сохраняем состояние кнопок
DelayMS 250 ;задержка 250мс (RC 1 МГц)
RJMP LOOP ;цикл
DELAY: LDI R17,0x02
DEL1: LDI R18,0xA6
DEL0: DEC R18
BRNE DEL0
DEC R17
BRNE DEL1
DEC R16
BRNE DELAY
RET
Re: ПОДСВЕТКА, проверьте ))
Добавлено: Чт мар 03, 2011 14:49:52
ARV
Engineer_Keen писал(а):А так с антидребезгом в виде задержки.
моя сестра - краткость
