Ассемблер (ASM) для AVR в вопросах и ответах
- MTF
- Нашел транзистор. Понюхал.
- Сообщения: 179
- Зарегистрирован: Чт янв 07, 2010 11:25:12
- Откуда: Москва
Всем привет!!!
Возникла следующая проблема, вторую неделю пытаюсь сделать сканирование 4 кнопок через таймер в котором возвращается в
регистр KEY код кнопки + короткое или длинное нажатие ,с изменением частоты автоповтора ,несколько людей на форуме подсказали примерый алгоритм ,ну и почитав кучу инфы в инете ,попытался написать код
микроконтроллер attiny2313
кварц 4 МГц
таймер
T1 CK/256
схема кнопок
вот что я навоял:
Вынесите вердикт по коду!!!!!!
Не могу придумать как при записи в Key еще и указывать длинное или короткое , в attiny2313 6 выводов pd
Можно ли как нибуть использовать лишний 7 бит как указатель длинного или короткого нажатия и как организовать автоповтор с определенной частотой ????
Возникла следующая проблема, вторую неделю пытаюсь сделать сканирование 4 кнопок через таймер в котором возвращается в
регистр KEY код кнопки + короткое или длинное нажатие ,с изменением частоты автоповтора ,несколько людей на форуме подсказали примерый алгоритм ,ну и почитав кучу инфы в инете ,попытался написать код
микроконтроллер attiny2313
кварц 4 МГц
таймер
T1 CK/256
схема кнопок
вот что я навоял:
Вынесите вердикт по коду!!!!!!
Код: Выделить всё
def tmkey = r17 ; счетчик времени
def key = r18 ; сюда пишется код кнопки для сравнения
def keyold = r19 ;
;основной цикл
main
cpi key, (код кнопки 1 короткое нажатие)
rcall Kn1short ;
cpi key, (код кнопки 2 короткое нажатие)
rcall Kn2short
cpi key, (код кнопки 1 длинное нажатие)
rcall Kn1long
cpi key, (код кнопки 2 длинное нажатие)
rcall Kn2long
rjmp main
T0_OVF
push r16
in r16,sreg ;push sreg
in r16, pind ;читаем порт D
andi r16 ,0b00110000 ;обнуляем лишние pd
cpi keyold ,r16 ;сравниваем со старым кодом
mov keyold, r16 ;
brne K1
inc tmkey ;tmkey +1
;короткое
cpi keyold , 5 ; ~0,1 c
breq keyset
;длинное нажатие
cpi keyold , 50 ; ~1 c
brne keyend ;если равно то end
.......................
.......................
.......................
rjmp keyset
K1:
clr tmkey
rjmp keyend
keyset:
mov key ,keyold
keyend:
out sreg,r16 ;Pop sreg
pop r16 ;pop R16
RETI
Не могу придумать как при записи в Key еще и указывать длинное или короткое , в attiny2313 6 выводов pd
Можно ли как нибуть использовать лишний 7 бит как указатель длинного или короткого нажатия и как организовать автоповтор с определенной частотой ????
- Вложения
-
- knopki.JPG
- (149.92 КБ) 506 скачиваний
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
я, по-моему, вам советовал обратить внимание на мой алгоритм? или не вам? и автоповтор, и все прочее. если хотите - можно флаг автоповтора делать в старшем бите - приходилось так делать и мне, хотя логичнее просто возвращать в нужный момент повторяемый код, да и все. необходимость различать ситуации, когда идет автоповтор или просто часто нажимается кнопка, возникает нечасто.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- MTF
- Нашел транзистор. Понюхал.
- Сообщения: 179
- Зарегистрирован: Чт янв 07, 2010 11:25:12
- Откуда: Москва
я, по-моему, вам советовал обратить внимание на мой алгоритм? или не вам? и автоповтор, и все прочее
ARV я просмотрел ваши коды, честно признаюсь не совсем понял т.к вы пишите на Си ,а я на asm пишу не так давно,поэтому полностью не разобратся !!!!
Если можите обьясните на словах
хотя логичнее просто возвращать в нужный момент повторяемый код, да и все
вот что пришло в голову
Код: Выделить всё
autorpt: .byte 1 ; для интервала между повтором
;длинное нажатие
cpi keyold , 50 ; ~1 c
brne keyend ;если равно то end
lds r16, autorpt
sub Tmkey, r16 ; 50 - autorpt через сколько надо повторять
rjmp keyset
А как сделать различие длинного и короткого нажатия одной и той же кнопки не доходит ?????
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
вроде комментарии в моем сишном коде очень подробные... я думал, вы разберетесь...
в функции "опроса" клавиатуры вы должны всегда знать определенную инфу о предыдущем обращении к этой функции: было нажатие или нет, если было - то какая именно кнопка нажата, а так же, было это первое нажатие или работает автоповтор.
1. если при обращении к функции выясняется, что кнопки не нажаты - вы все эти промежуточные состояния обнуляете.
2. если кнопка нажата - смотрите, совпадает она с предыдущим разом или нет.
3. если не совпадает - запоминаете ее (чтобы в след. раз вспомнить), и устанавливаете признак первого нажатия.
4. затем смотрите на признак первого нажатия. если он установлен - надо ждать, скажем, 1 секунду. если за эту секунду не было отпускания кнопки - вы ставите флаг автоповтора (или сбрасываете флаг первого нажатия - это одно и то же) и возвращаете код кнопки. если за время ожидания кнопку отпустили - поступаете как в п.1.
5. если флаг автоповтора стоит (или сброшен флаг первого нажатия) вы ждете, скажем, 0,3 секунды (проверяя на отпускание кнопки - если отпустили - п.1), а потом возвращаете код кнопки.
таким образом, ваша функция:
1. возвратит 0 немедленно при отпускании кнопки и при отсутсвии нажатия.
2. возвратит мгновенно код нажатой кнопки
3. если кнопка нажата и не отпущена, то через 1 секунду удержания функция начнет каждые 0,3 секунды повторять код нажатой кнопки.
если хотите, при возврате с автоповтором добавляйте к коду кнопки старший бит, как признак автоповтора, но это, имхо, лишнее для большинства случаев.
в функции "опроса" клавиатуры вы должны всегда знать определенную инфу о предыдущем обращении к этой функции: было нажатие или нет, если было - то какая именно кнопка нажата, а так же, было это первое нажатие или работает автоповтор.
1. если при обращении к функции выясняется, что кнопки не нажаты - вы все эти промежуточные состояния обнуляете.
2. если кнопка нажата - смотрите, совпадает она с предыдущим разом или нет.
3. если не совпадает - запоминаете ее (чтобы в след. раз вспомнить), и устанавливаете признак первого нажатия.
4. затем смотрите на признак первого нажатия. если он установлен - надо ждать, скажем, 1 секунду. если за эту секунду не было отпускания кнопки - вы ставите флаг автоповтора (или сбрасываете флаг первого нажатия - это одно и то же) и возвращаете код кнопки. если за время ожидания кнопку отпустили - поступаете как в п.1.
5. если флаг автоповтора стоит (или сброшен флаг первого нажатия) вы ждете, скажем, 0,3 секунды (проверяя на отпускание кнопки - если отпустили - п.1), а потом возвращаете код кнопки.
таким образом, ваша функция:
1. возвратит 0 немедленно при отпускании кнопки и при отсутсвии нажатия.
2. возвратит мгновенно код нажатой кнопки
3. если кнопка нажата и не отпущена, то через 1 секунду удержания функция начнет каждые 0,3 секунды повторять код нажатой кнопки.
если хотите, при возврате с автоповтором добавляйте к коду кнопки старший бит, как признак автоповтора, но это, имхо, лишнее для большинства случаев.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- MTF
- Нашел транзистор. Понюхал.
- Сообщения: 179
- Зарегистрирован: Чт янв 07, 2010 11:25:12
- Откуда: Москва
точно сделать по алгоритму ARV не получилось ,слишком сложно для меня
вот что сделал ,но корректно не работает ,кто нибудь может посмотреть правильность написания кода ,или опять что нибудь не так делаю??????
вот что сделал ,но корректно не работает ,кто нибудь может посмотреть правильность написания кода ,или опять что нибудь не так делаю??????
Код: Выделить всё
def tmkey = r17 ; счетчик времени
def key = r18 ; сюда пишется код кнопки для сравнения
def keyold = r19 ;
autorpt: .byte 1 ; для интервала между повтором
;основной цикл
main
ser key
Key1:
cpi key , 255
breq Key1
cpi key, (код кнопки 1 короткое нажатие)
rcall Kn1short ;
cpi key, (код кнопки 2 короткое нажатие)
rcall Kn2short
cpi key, (код кнопки 1 длинное нажатие)
rcall Kn1long
cpi key, (код кнопки 2 длинное нажатие)
rcall Kn2long
rjmp main
T0_OVF
push r16
in r16,sreg ;push sreg
in r16, pind ;читаем порт D
ori r16 ,0b00110000 ;уст в 1 лишних pd
cpi r16 ,255 ;
breq K1 ;если все 1 то clr
cpi keyold ,r16 ;сравниваем со старым кодом
mov keyold, r16 ;
brne K1 ;не совпад со старым кодом кнопки
inc tmkey ;tmkey +1
;короткое
cpi tmkey , 5 ; 0,1 c
brne keyend
mov key ,keyold
rjmp keyend
;длинное нажатие
cpi tmkey , 50 ; более 1 c
brne keyend ; если не равно то end
lds r16, autorpt
sub tmkey , r16 ; 50 - autorpt (0,3c)
ldi r16,0x80 ; 0b10000000
or r16,keyold ; r16 + KeySold = 80h + Keyold
mov key ,r16
rjmp keyend
K1:
clr tmkey ;0
; clr Keyold ;0
rjmp keyend
keyend:
out sreg,r16 ;Pop sreg
pop r16 ;pop R16
RETI
- aleksasm
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср ноя 25, 2009 18:56:55
- Откуда: Lithuania
Просьба о помощи. Имеется фаил прошивки PIC12F675 в формате аsm, сколько не бьюсь никак не могу перекомпилировать в нех файл. Много разных конвертеров перепробовал, ерунда какая то получается. Помогите, я так понимаю спецу тут на 5 мин.
- Вложения
-
- serv675c.asm
- (7.17 КБ) 408 скачиваний
- Cat Career
- Родился
- Сообщения: 12
- Зарегистрирован: Пн янв 11, 2010 12:51:31
- Откуда: Санкт-Петербург
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Присвоить имя биту
а чтобы заменить
надо макрос написать.
Код: Выделить всё
.equ RS=pb0а чтобы заменить
Код: Выделить всё
sbi PORTB,0надо макрос написать.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
если используете нормальные хидеры (inc-файлы описаний микроконтроллеров), то все биты всех стандартных регистров там уже описаны:Cat Career писал(а):Народ, не подскажете как в атмеловском ассемблере присваивать имена битам порта? допустим чтобы не писать
sbi PORB, 0
а писать допустим
sbi RS
подразумевая под RS PORB, 0?
Код: Выделить всё
sbi PORTB, PB0если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Cat Career писал(а):а писать допустим
sbi RS
подразумевая под RS PORB, 0?
AVR assembler 2 уже немножко научился понимать C-шный препроцессор, поэтому можно так
Код: Выделить всё
#define RS PORTB,0
sbi RSЛень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- MTF
- Нашел транзистор. Понюхал.
- Сообщения: 179
- Зарегистрирован: Чт янв 07, 2010 11:25:12
- Откуда: Москва
Народ, кто нибуть может подсказать как с помощью входа INT0 или INT1 attiny2313 принимать код RC5 ,через INT понадобилось для того чтобы с помощью кнопки пульта ON/OFF пробуждать контроллер !!!!!!!!!
не через INT с любого входа pd понял как и даже попробовал как описано в datasheet avr410 RC5
вопрос: если делать через INT , как нибудь можно упростить код для приема RC5 ??????
не через INT с любого входа pd понял как и даже попробовал как описано в datasheet avr410 RC5
вопрос: если делать через INT , как нибудь можно упростить код для приема RC5 ??????
Нужна помощь.
Только начинаю разбираться в ассемблере, возникла необходимость установить/сбросить не кокретный разряд порта ввода/вывода, а динамичный, то есть во время работы микроконтроллера номер разряда для сброса/установки изменяется. Ну например, есть у меня цикл, от 0 до 7, и надо поочередно установить каждый разряд PORTB, но ведь SBI не может использовать в качестве разряда для установки значение из регистра, или откуда либо еще, только заданное при компилляции число. Как же тогда быть?
Только начинаю разбираться в ассемблере, возникла необходимость установить/сбросить не кокретный разряд порта ввода/вывода, а динамичный, то есть во время работы микроконтроллера номер разряда для сброса/установки изменяется. Ну например, есть у меня цикл, от 0 до 7, и надо поочередно установить каждый разряд PORTB, но ведь SBI не может использовать в качестве разряда для установки значение из регистра, или откуда либо еще, только заданное при компилляции число. Как же тогда быть?
- aleksasm
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср ноя 25, 2009 18:56:55
- Откуда: Lithuania
aleksasm писал(а):Просьба о помощи. Имеется фаил прошивки PIC12F675 в формате аsm, сколько не бьюсь никак не могу перекомпилировать в нех файл. Много разных конвертеров перепробовал, ерунда какая то получается. Помогите, я так понимаю спецу тут на 5 мин.
Задачку решил сам, вижу тут не очень хотят помогать чайникам(жаль).
- evgeniy66
- Нашел транзистор. Понюхал.
- Сообщения: 151
- Зарегистрирован: Пт май 01, 2009 08:58:42
- Откуда: г. Коломна
- Контактная информация:
aleksasm писал(а):aleksasm писал(а):Просьба о помощи. Имеется фаил прошивки PIC12F675 в формате аsm, сколько не бьюсь никак не могу перекомпилировать в нех файл. Много разных конвертеров перепробовал, ерунда какая то получается. Помогите, я так понимаю спецу тут на 5 мин.
Задачку решил сам, вижу тут не очень хотят помогать чайникам(жаль).
Тема называется "Ассемблер (ASM) для AVR в вопросах и ответах", при чем тут PIC?
RK3DUQ
Savelek писал(а):Нужна помощь.
Только начинаю разбираться в ассемблере, возникла необходимость установить/сбросить не кокретный разряд порта ввода/вывода, а динамичный, то есть во время работы микроконтроллера номер разряда для сброса/установки изменяется. Ну например, есть у меня цикл, от 0 до 7, и надо поочередно установить каждый разряд PORTB, но ведь SBI не может использовать в качестве разряда для установки значение из регистра, или откуда либо еще, только заданное при компилляции число. Как же тогда быть?
Ну так что, неужели никто не может ответить на мой вопрос? Ладно, переформулирую свой вопрос - можно ли сбросить/установить разряд в порте ввода/вывода, при этом указав номер рязряда через значение одного из регистров общего назначения. Ну например, сначала записываю в r16 число 4, а потом устанавливаю в 1 разряд PORTB под номером , при этом номер устанавливаемого рязряда должен взяться из r16.
_noise писал(а):Savelek, http://radiokot.ru/forum/viewtopic.php?t=20076 . С таблицей красиво. Не надо оверпостить, здесь не чат.
_noise, спасибо за ссылку, то что нужно!

-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
Savelek писал(а):_noise писал(а):Savelek, http://radiokot.ru/forum/viewtopic.php?t=20076 . С таблицей красиво. Не надо оверпостить, здесь не чат.
_noise, спасибо за ссылку, то что нужно!Правда я думал, что ассемблеру можно как-то сказать, чтобы он брал значение из регистра или еще откуда-то, но, видимо, так нельзя. Но ничего, так даже интереснее.
Ассемблер не может сам сделать то, что не поддерживается процессором. Ну а АТмеги не имеют команд, позволяющих обращаться к битам косвенно -- т.е. по номерам битов, хранящимся в регистрах. Вот к ОЗУ обращаться косвенно можно (команды вида LD Rn, X и т.п.) -- но это доступ к байтам, а не отдельным битам.
- Pooher
- Мучитель микросхем
- Сообщения: 491
- Зарегистрирован: Вс янв 07, 2007 01:45:48
- Откуда: Российская Федерация, будь она неладна...
Savelek писал(а):Нужна помощь.
Только начинаю разбираться в ассемблере, возникла необходимость установить/сбросить не кокретный разряд порта ввода/вывода, а динамичный, то есть во время работы микроконтроллера номер разряда для сброса/установки изменяется. Ну например, есть у меня цикл, от 0 до 7, и надо поочередно установить каждый разряд PORTB, но ведь SBI не может использовать в качестве разряда для установки значение из регистра, или откуда либо еще, только заданное при компилляции число. Как же тогда быть?
Ну не забывайте про родные логические операции.
На пример:
Код: Выделить всё
in tmp, PORTX
; В tmp1 установлен бит, который надо установить в порте
or tmp, tmp1 ; лог И регистров
out PORTX, tmp
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Pooher писал(а):Savelek писал(а):Нужна помощь.
Только начинаю разбираться в ассемблере, возникла необходимость установить/сбросить не кокретный разряд порта ввода/вывода, а динамичный, то есть во время работы микроконтроллера номер разряда для сброса/установки изменяется. Ну например, есть у меня цикл, от 0 до 7, и надо поочередно установить каждый разряд PORTB, но ведь SBI не может использовать в качестве разряда для установки значение из регистра, или откуда либо еще, только заданное при компилляции число. Как же тогда быть?
Ну не забывайте про родные логические операции.
На пример:Код: Выделить всё
in tmp, PORTX
; В tmp1 установлен бит, который надо установить в порте
or tmp, tmp1 ; лог И регистров
out PORTX, tmp
Извините пожалуйста за возможно глупый вопрос, но что случится, если сделать логическую операцию между двумя регистрами (т.е. двумя байтами)? Ну например логическое ИЛИ. Будут поочередно сравниваться одинаковые п осчету биты двух регистров? А результат? Результат сравнения запишется в первый из сравниваемых регистров?
И еще вопрос - у Вас в коде команда "or tmp,tmp1", а в комментариях указано что это логическое И. Но ведь or это или... Да и для установки бита, наверное, нужно использовать лог. ИЛИ. Или я не прав?
