реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Кнопки на atmega16
SpiritCoat
сообщение Jul 30 2008, 09:53
Сообщение #1





Группа: Новичок
Сообщений: 11
Регистрация: 14-04-08
Пользователь №: 36 773



Искал поиском, но самого простого и базового объяснения нигде не нашел.
В общем идея такова: нажимается кнопочка и двоичное число, высвечиваемое на светодеодах, увеличивается на единичку. Деоды прикреплены к порту D, кнопочка висит на порте А. Вот код:

Код
.include "m16def.inc"

.def     Temp=R16
.def     Temp1=R17
.def     Temp2=R18
.def     Temp3=R19
.def     Temp4=R20


.cseg
.org 0

ldi Temp, 0b11111111  
out DDRB,Temp        

ldi Temp,0b00000001    
out PortB,Temp        

BUT:

sbis PinA,0x00; если нажато - переходим к SWITCH
rjmp BUT

SWITCH:

inc Temp
out PortB,Temp
ldi Temp1,0
ldi Temp2,0

DLY:

dec Temp1 ; задержка
brne DLY
dec Temp2
brne DLY

rjmp BUT


Вроде бы все логично, но почему-то работает как угодно, но не так как описано. Что я делаю неверно?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 30 2008, 10:05
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Для начала - нет подавления дребезга.
Дальше - нет детектирования отпускания кнопки. То есть, при нажатии и удержании числа просто будут "бежать". В результате, могу предположить, что получился неплохой генератор случайных чисел.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 30 2008, 10:09
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(SpiritCoat @ Jul 30 2008, 12:53) *
Вроде бы все логично, но почему-то работает как угодно, но не так как описано. Что я делаю неверно?

smile.gif
А как описано?

Как говорил Сергей Борщ "Даю наводку" smile.gif

1) У тебя когда кнопка нажата будет с периодичностью задержки наращиваться значение выводимое в порт.
2) Кнопку обычно подключают на 0. А оборванный выход подпирают резистором (Или внутренней подпоркой)
3) Есть такое понятие как "гашение дребезга"

Видишь ли любую задачу в программировании можно реализовать десятком способов. Чтобы не гасить дребезг предлагаю следующий алгоритм.

a:
ждём нуля на кнопке. если нет то на а
задержка 0.3 сек
б:
ждём 1 на кнопке. если нет то на б
задержка 0.3 сек
инкрементируем значение
выводим в порт
переход на а
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 30 2008, 10:15
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(SpiritCoat @ Jul 30 2008, 15:53) *
Деоды прикреплены к порту D, кнопочка висит на порте А. Вот код:

Код
SWITCH:

inc Temp
out PortB,Temp


Диоды к порту D, а инкрементируется порт B?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 30 2008, 10:19
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(SpiritCoat @ Jul 30 2008, 12:53) *
но почему-то работает как угодно, но не так как описано. Что я делаю неверно?

У вас не учитывается дребезг кнопки и длительное удержание.
Фильтруйте события:
i.e. если кнопка повторно нажата быстрее чем за 20ms - дребезг,
если кнопку не отпускали значит не нужно ничего увеличивать (нажатие одно)
Go to the top of the page
 
+Quote Post
SpiritCoat
сообщение Jul 30 2008, 11:36
Сообщение #6





Группа: Новичок
Сообщений: 11
Регистрация: 14-04-08
Пользователь №: 36 773



Спасибо всем, кто отписался! Этот алгоритм:

Цитата(SasaVitebsk @ Jul 30 2008, 14:09) *
a:
ждём нуля на кнопке. если нет то на а
задержка 0.3 сек
б:
ждём 1 на кнопке. если нет то на б
задержка 0.3 сек
инкрементируем значение
выводим в порт
переход на а


действительно работает! Только что успешно протестил. Правда не слишком стабильно, но, я буду работать над этим smile.gif

И еще мелкий вопрос, тоже нигде не нашел: как на меге16 инициализировать стек? Видел следующий пример кода:

Код
ldi Temp,RamEnd      
out SPL,Temp


Но компилятор ругается на RamEnd. Подскажите, что надо исправить, чтобы работало на atmega16. Заранее спасибо.

Сообщение отредактировал SpiritCoat - Jul 30 2008, 11:37
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 30 2008, 11:40
Сообщение #7


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(SpiritCoat @ Jul 30 2008, 14:36) *
Код
ldi Temp,RamEnd      
out SPL,Temp

Но компилятор ругается на RamEnd.

ldi Temp, High( RAMEND)
out SPH, Temp
ldi Temp, Low( RAMEND)
out SPL, Temp

Цитата
тоже нигде не нашел

плохо искали. стр. 46 ДШ на М16.
"The most typical and general program setup for the Reset and Interrupt Vector Addresses"
Go to the top of the page
 
+Quote Post
SpiritCoat
сообщение Aug 3 2008, 20:42
Сообщение #8





Группа: Новичок
Сообщений: 11
Регистрация: 14-04-08
Пользователь №: 36 773



Помогите разобраться с прикручиванием нескольки кнопок. Например, при нажатии нулевой число увеличивается на единицу, а при нажатии первой – уменьшается. Написал код, но снова что-то не так:

Код
.include "m16def.inc"

.def temp1=R16
.def temp2=R17
.def temp3=R18
.def temp4=R19
.def temp=R20

.dseg

Line: .byte 2

.cseg
.org 0


ldi temp, High(RamEnd)
out SPH, Temp
ldi temp, Low(RamEnd)
out SPL, Temp

ldi temp, 0b11111111
out DDRB, temp
ldi Temp,0b00000001    
out PortB,Temp    

KeyRead:

in temp1,PinA      ; читаем порт А
sts Line, temp1    ; записываем результат в ОЗУ
rcall DLY          ; Задержка
cpi Temp1,0          
brne KeyTest       ; если что-то нажато - переходим на обработку
rjmp KeyRead       ;если ничего не нажато - сначала

KeyTest:
lds temp1, line      ; загружаем результат чтения порта
cpi temp1, 0b00000001; если нажата нулевая кнопка переходим к But0
breq But0
cpi temp1, 0b00000010; если нажата первая кнопка переходим к But1
breq But1

But0:

inc Temp             ;инкремент
out PortB,Temp
rcall DLY            ; вызываем задержку
rjmp KeyRead         ; в начало

But1:

dec Temp             ;декремент
out PortB,Temp
rcall DLY            ;задержка
rjmp KeyRead

;----------------------------------------------------------------------

DLY:

ldi Temp1,0
ldi Temp2,0

Loop:

dec Temp1
brne Loop
dec Temp2
brne Loop

ret


А точнее, кнопки не откликаются вовсе. Наставьте на путь истиный smile.gif
Go to the top of the page
 
+Quote Post
Paulina
сообщение Aug 5 2008, 13:49
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607



Цитата(SpiritCoat @ Aug 3 2008, 23:42) *
Код
ldi temp, 0b11111111
out DDRB, temp
ldi Temp,0b00000001    
out PortB,Temp

Здесь устанавливаете все биты PORTB на выход, как же кнопки будут работать?
Цитата(SpiritCoat @ Aug 3 2008, 23:42) *
Код
in temp1,PinA; читаем порт А
sts Line, temp1; записываем результат в ОЗУ
rcall DLY; Задержка
cpi Temp1,0

содержимое temp1 после вызова задержки пропадет, поэтому строка cpi temp1, 0 не имеет смысла. используйте стек или другие регистры
Цитата(SpiritCoat @ Aug 3 2008, 23:42) *
Код
Loop:

dec Temp1
brne Loop
dec Temp2
brne Loop

ret

а тут будет зацикливание. сделайте лучше так:
Код
Loop:

dec Temp1
brne Loop

Loop2:

dec Temp2
brne Loop2

ret

а кнопки лучше подключить, как советует SasaVitebsk, с внутренней подтяжкой (DDRx=0, PORTx=1), соответственно проверяете на 0

Сообщение отредактировал Paulina - Aug 5 2008, 14:07
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 09:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.0145 секунд с 7
ELECTRONIX ©2004-2016