Страница 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)

Код: Выделить всё

DDRA=0x00
DDRB=0xFF
Это что такое? :))) Раз уж прога на ассемблере так и надо писать на ассемблере

Код: Выделить всё

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]


Бррррррр... :o Эт Я так предположил, что программа будет работать именно так, как вы написали в этом примере. Повторюсь, на атмеге это моя первая программа, пишу её "вслепую", т.к. стенда под рукой нет, и эмулятора как Я понял не существует, вот... и не уверен будет ли работать код который Я написал, так как мне надо. А нужно, чтобы после отпускания кнопки светодиод продолжал светиться)))

Исходя из выше сказанного вами написанного: лучше стек организовывать самому чтоли??? Т.е. выделить сегмент памяти и туда закидывать сохраненную информацию??? И как его инициализировать?

Re: ПОДСВЕТКА, проверьте ))

Добавлено: Пн фев 28, 2011 15:13:56
Fasterpast
и эмулятора как Я понял не существует
:shock:
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 часа провозился так ничего не придумал... :cry:

Re: ПОДСВЕТКА, проверьте ))

Добавлено: Вт мар 01, 2011 11:52:59
O-LED
3). Немогу додуматься каким образом потушить светодиод по нажатию кнопки, 3 часа провозился так ничего не придумал... :cry:
чтоб потушить светодиод, нужно снять с него напряжение. Вы за 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 писал(а):А так с антидребезгом в виде задержки.
моя сестра - краткость :)))