Страница 97 из 400
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср авг 03, 2011 19:34:59
qmix
vit007 писал(а):собрал внешнюю подтяжку и все правильно заработало, сп Gudd-Head и DX168B
теперь немного о птицах...
объясните как работает первая строка... понятно что значение 7 пина вводим, а куда...
в инструкции работы порта на ввод?
потому что так
in temp, PinD - вроде записываем состояние порта в рег.
вроде одно и тоже, но как-то не понятно...
сам
sbis, где хранит решение... и вообще сам процесс программы подвисает на ожидание? (хочется сделать "без этого вот этого не будет")
и вот
rjmp косвенный (непонятен смысл) переход. всегда его использовал для банального прыжка программы, а тут получается какая-то связь
sbis...
"ни чего не понимаю!"
DX168B, если испоьзуем вн. подтяжку порта, то лучше кн. вешать на один порт, а вывод на др. порт, чтоб не нарушать...
Не в обиду будет сказано, но как ламер ламеру поделюсь своим пониманием что такое sbis. как вы понимаете она смотрит определенный бит определенного порта. точнее она проверяет какой уровень на порту (высокийй или низкий). никуда его не закидывает, просто проверяет. Так вот, если бит в порту установлен (лог.1), то следующая команда пропускается), соответственно, если там лог.0, то следующая команда выполняется. вот вам и взаимосвязь со следующей rjmp (хотя это может быть что угодно).
кстати команда sbic это тоже самое, но наоборот: пропускает если лог.0 и выполняет если лог.1
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт авг 04, 2011 10:22:18
vit007
Сп. Gudd-Head, qmix – понял как…
Немного перефразирую, как понял:
Sbis (или sbic) работает в паре со след строкой проги (не зависимо что там).
Первое PinD это выбор порта, по кот. будет произведен мониторинг конкретного пина: PinD7 (или просто можно записать цифрой «7»)
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт авг 04, 2011 13:35:57
Ethereal
SBIS SPEC_REG, BIT
Проверить бит BIT в спец.регистре SPEC_REG и пропустить следующую команду, если он выставлен.
SBIС SPEC_REG, BIT
Проверить бит BIT в спец.регистре SPEC_REG и пропустить следующую команду, если он сброшен.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пт авг 05, 2011 13:00:56
DX168B
На счёт sbis и sbic уже объяснили.
Просто лишний раз напомню. Все команды ассемблера - это аббревиатуры.
SBIS -
Skip next if
Bit in
I\O is
Set. (Пропустить следующую инструкцию, если бит в рег. В\В установлен [лог.1])
SBIC -
Skip next if
Bit in
I\O is
Cleared. (Пропустить следующую инструкцию, если бит в рег. В\В сброшен [лог.0])
На счёт портов и подтяжек никто не сказал.
Все отдельные входы и отдельные выходы. (например, светодиоды индикации и кнопки)
надо разместить в одном порту и использовать команды для чтения sbis и sbic. Ну и для выходов
cbi PortX, PinX и sbi PortX, PinX. Можно применить и команду для чтения in и для записи out.
Но только в этом случае, при чтении или записи, надо либо выкинуть лишние биты командой and или andi, либо при записи выставить не нужные биты командами or или ori перед отправкой в порт. Лучше же читать каждую ногу в отдельности или управлять каждой ногой в отдельности.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 14:05:03
sinobi
Подскажите есть текст программы-писал не я,не могу понять как работает такой макрос
.Macro Outi
Ldi Temp, @1
Out @0, Temp
.EndMacro
вот еще
.Macro DelayMs
Ldi YL,LOW(@0)
Ldi YH,HIGH(@0)
DelayUs_Loop:
DelayUs(1000)
Sbiw Y,1
Brne DelayUs_Loop
.EndMacro
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 14:21:39
IfoR
Дык чего тут? Я скажу тоже самое, что у тебя и написано.
Для Outi: 2-ой параметр-константа заносится в регистр Temp а затем в 1 параметр-порт заносится регистр Temp, в котором сохранён параметр-константа.
Для DelayMs: Принимает один параметр - время в миллисекундах, который заносится в регистр Y. Затем вызывается макрос DelayUs(1000) Y раз.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 14:44:26
sinobi
я просто не монимаю откуда береться константа @1 и @0- в начале программы их не объявляли
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 14:52:04
IfoR
Это не константы. Эта параметры, которые передаются макросу.
Например, вызвав макрос так:
в параметр @0 будет передано DDRB, а в @1 - 0xFF.
Т.е. число после @ указывает номер параметра, начиная от 0 слева на право, которые перечисляются через запятую. Данный макрос развернётся так:
т.е. все @ заменяются соответствующими параметрами.
Параметров в макросе можно выставить сколько угодно, но обычно 2-3 параметра хватает.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 14:56:17
DX168B
Это условные обозначения операндов. Когда пишете вызов макроса, то его аргументы подставляются вместо этих @0 и @1.
К примеру:
Outi SPL, RAMend
Сам макрос:
.MACRO Outi
ldi temp, @1
out @0, temp
.ENDMACRO
В итоге, получится это:
ldi temp, RAMend
out SPL, temp
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 15:27:35
sinobi
Понятно,спасибо
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 15:41:07
sinobi
Вот еще вопрос -не могу разобраться надо сравнить число с переменной в буфере -число CC877F9B,разкидал по трем регистрам
.Equ SER0=0xCC
.Equ SER1=0x87
.Equ SER2=0x7F
.Equ BUT=0x9B
Проверяю вот так
Save2:
Cpi R27, SER2
Brne Save2
Cpi R26, SER1
Brne Save2
Cpi R25, SER0
Brne Save2
Cpi R28, BUT
Brne Save2
если переменная равна то
Sbi DDRB, LED ; LED - на вывод
Sbi PORTB, LED ; Зажечь зеленый светодиод!
Но не работает-подозреваю что не правильно порядок опроса сделал-нарушаю стек ,подскажите как правильно оформить
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 15:44:29
IfoR
Ваши команды не используют стек.
Несовсем понятно, как вы раскидали 4-х байтовое число по трём регистрам.
И, собственно, как именно оно не работает? Какое содержание регистров в данный момент?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 15:51:26
sinobi
Извиняюсь-правильно по четырем,переменная в буфере такая же как и число вот я и сравнить пытаюсь -но светодиод не загорается.Меня интересует правильно ли выполнены команды сравнения чисел.Я так понял должно быть первым вошел,последним вышел
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 16:04:11
DX168B
А так не пробовали?
Код: Выделить всё
.Equ SER0=0xCC
.Equ SER1=0x87
.Equ SER2=0x7F
.Equ BUT=0x9B
.....
.......
...
ldi r16, проверяемое число
;------------------------------
MAIN:
ldi ZL, Low(ARRAY*2)
ldi ZH, High(ARRAY*2)
ldi r18, 0x04
;------------------------------
MAIN_LOOP:
lpm r17, Z+
cp r16, r17
breq LED_ON
dec r18
brne MAIN_LOOP
rjmp NO_LED
;------------------------------
LED_ON:
sbi PORTx, PINx
NO_LED:
....
....
;------------------------------
ARRAY:
.db SER0, SER1, SER2, BUT
Можно и так:
Код: Выделить всё
.Equ SER0=0xCC
.Equ SER1=0x87
.Equ SER2=0x7F
.Equ BUT=0x9B
.............
......
;--------------------
MAIN:
ldi r16, проверяемое число
cpi r16, SER0
breq LED_ON
cpi r16, SER1
breq LED_ON
cpi r16, SER2
breq LED_ON
cpi r16, BUT
breq LED_ON
rjmp NO_LED
;------------------------
LED_ON:
sbi PORTx, PINx
;------------------------
NO_LED:
.....
.......
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 17:27:43
sinobi
DX168B писал(а):А так не пробовали?
Код: Выделить всё
MAIN:
ldi r16, проверяемое число
cpi r16, SER0
breq LED_ON
cpi r16, SER1
breq LED_ON
cpi r16, SER2
breq LED_ON
cpi r16, BUT
breq LED_ON
rjmp NO_LED
;------------------------
LED_ON:
sbi PORTx, PINx
;------------------------
NO_LED:
.....
.......
А разве в регистр один такое число поместиться?Извиняюсь за вопрос просто я еще не силен в программировании
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 17:34:09
IfoR
Ну так, дело в том, что как сравнивать, это зависит только от вас. Вы же разрабатываете программу?

Программа-то у вас должна работать правильно, но я не знаю как вы храните число в регистрах.

Просто проверьте ещё раз как вы храните число в регистрах и константе и сверьте порядок проверки.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 17:48:36
IfoR
Кстати, как вариант. Такие числа лучше хранить целиком. Тут на помощь приходят директивы препроцессора.
Например, у вас есть число 56ADEAD7. Тогда объявить его можно так:
Где #define - директива препроцессора; longlong - имя объявленной константы; 0x56ADEAD7 - значение константы.
А что бы взять отдельный байт отсюда, можно написать такой макрос, который записывается где нить вверху:
Данный макрос вызывается так:
где x - константа; y - номер возвращаемого байта относительно младшего разряда начинаемого с 0.
Теперь в коде можно написать что нить типа:
Код: Выделить всё
#define byte(x,y) ((x >> (y*8)) & 0xFF)
#define longlong 0x56ADEAD7
...
cpi R16, byte(longlong, 0)
brne SAVE
cpi R17, byte(longlong, 1)
brne SAVE
cpi R18, byte(longlong, 2)
brne SAVE
cpi R19, byte(longlong, 3)
brne SAVE
Сразу говорю. Код только что из головы и может не работать либо требовать поправлений
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 17:50:48
DX168B
Так вам надо сравнить два 32х-битных числа? И если совпадёт, то зажечь светодиод?
Или нужно сравнить один байт с четырьмя байтами и в случае, если он совпадёт с одним из этих четырех байтов, зажечь светодиод?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 17:57:37
sinobi
DX168B писал(а):Так вам надо сравнить два 32х-битных числа? И если совпадёт, то зажечь светодиод?
Да именно число СС877F9B сравнить с тем что в буфере,если сходятся то зажечь светодиод
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 18:02:17
DX168B
Да проще простого.
Сначала надо занести число, которое будет у нас эталоном в массив.
Предположительно, наш буфер лежит в ОЗУ, в массиве buffer
А код будет таким:
Код: Выделить всё
.Equ SER0=0xCC
.Equ SER1=0x87
.Equ SER2=0x7F
.Equ BUT=0x9B
;--------------------------
.dseg
buffer: .byte 4
;--------------------------
.cseg
.org 0x0000
.....
........
.........
;--------------------------
INIT_F-D_LOOP:
ldi ZL, Low(ARRAY*2) ;Прихватываем массив в ПЗУ
ldi ZH, High(ARRAY*2)
ldi YL, Low(buffer) ;Прихватываем буфер в ОЗУ
ldi YH, High(buffer)
ldi r18, 0x04 ;Количество чисел для сравнения.
;--------------------------
F-D_LOOP:
lpm r16, Z+ ;Загружаем байт из ПЗУ в р16
ld r17, Y+ ;Загружаем байт из буфера в ОЗУ в р17
cp r16, r17 ;Сравним их (р16 и р17)
brne ERROR ;Если не равны, то спрыгиваем с цикла
dec r18 ;Иначе, уменьшим счётчик на 1
brne F-D_LOOP ;И сравним следующие числа.
;-------------------------- Если всё совпало, то зажигаем светодиод
sbi PORTx, PxX ;Зажигаем светодиод
rjmp КУДА-ТО
;--------------------------
ERROR: ;Иначе, предпринимаем действия, если не совпало.
cbi PORTx, PxX ;Например, погасим светодиод
rjmp КУДА-ТО
;--------------------------
ARRAY: ;А это массив образцового числа для сравнения с буфером.
.db SER0, SER1, SER2, BUT
Просто загружаем байты по очереди и сравниваем их.
Если весь цикл прошёл успешно, то зажигаем светодиод.
А если сорвались с цикла (какое-то из чисел не соответствует), то выполняем действия под меткой ERROR.