собрал внешнюю подтяжку и все правильно заработало, сп Gudd-Head и DX168B теперь немного о птицах...
Код:
sbis PIND, PIND7 rjmp EVENT_00
объясните как работает первая строка... понятно что значение 7 пина вводим, а куда... в инструкции работы порта на ввод? потому что так in temp, PinD - вроде записываем состояние порта в рег. вроде одно и тоже, но как-то не понятно... сам sbis, где хранит решение... и вообще сам процесс программы подвисает на ожидание? (хочется сделать "без этого вот этого не будет") и вот rjmp косвенный (непонятен смысл) переход. всегда его использовал для банального прыжка программы, а тут получается какая-то связь sbis... "ни чего не понимаю!" DX168B, если испоьзуем вн. подтяжку порта, то лучше кн. вешать на один порт, а вывод на др. порт, чтоб не нарушать...
Не в обиду будет сказано, но как ламер ламеру поделюсь своим пониманием что такое sbis. как вы понимаете она смотрит определенный бит определенного порта. точнее она проверяет какой уровень на порту (высокийй или низкий). никуда его не закидывает, просто проверяет. Так вот, если бит в порту установлен (лог.1), то следующая команда пропускается), соответственно, если там лог.0, то следующая команда выполняется. вот вам и взаимосвязь со следующей rjmp (хотя это может быть что угодно). кстати команда sbic это тоже самое, но наоборот: пропускает если лог.0 и выполняет если лог.1
Немного перефразирую, как понял: Sbis (или sbic) работает в паре со след строкой проги (не зависимо что там). Первое PinD это выбор порта, по кот. будет произведен мониторинг конкретного пина: PinD7 (или просто можно записать цифрой «7»)
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пт авг 05, 2011 13:00:56
Друг Кота
Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52 Сообщений: 4468 Откуда: Главный Улей России (Moscow)
Рейтинг сообщения:0
На счёт 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 перед отправкой в порт. Лучше же читать каждую ногу в отдельности или управлять каждой ногой в отдельности.
_________________ I am DX168B and this is my favourite forum on internet!
Подскажите есть текст программы-писал не я,не могу понять как работает такой макрос .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
Дык чего тут? Я скажу тоже самое, что у тебя и написано. Для Outi: 2-ой параметр-константа заносится в регистр Temp а затем в 1 параметр-порт заносится регистр Temp, в котором сохранён параметр-константа.
Для DelayMs: Принимает один параметр - время в миллисекундах, который заносится в регистр Y. Затем вызывается макрос DelayUs(1000) Y раз.
Это не константы. Эта параметры, которые передаются макросу. Например, вызвав макрос так:
Код:
outi DDRB, 0xFF
в параметр @0 будет передано DDRB, а в @1 - 0xFF. Т.е. число после @ указывает номер параметра, начиная от 0 слева на право, которые перечисляются через запятую. Данный макрос развернётся так:
Код:
Ldi Temp, 0xFF Out DDRB, Temp
т.е. все @ заменяются соответствующими параметрами. Параметров в макросе можно выставить сколько угодно, но обычно 2-3 параметра хватает.
Вот еще вопрос -не могу разобраться надо сравнить число с переменной в буфере -число 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 ; Зажечь зеленый светодиод! Но не работает-подозреваю что не правильно порядок опроса сделал-нарушаю стек ,подскажите как правильно оформить
Последний раз редактировалось sinobi Вс авг 07, 2011 15:45:41, всего редактировалось 1 раз.
Ваши команды не используют стек. Несовсем понятно, как вы раскидали 4-х байтовое число по трём регистрам. И, собственно, как именно оно не работает? Какое содержание регистров в данный момент?
Извиняюсь-правильно по четырем,переменная в буфере такая же как и число вот я и сравнить пытаюсь -но светодиод не загорается.Меня интересует правильно ли выполнены команды сравнения чисел.Я так понял должно быть первым вошел,последним вышел
Ну так, дело в том, что как сравнивать, это зависит только от вас. Вы же разрабатываете программу? Программа-то у вас должна работать правильно, но я не знаю как вы храните число в регистрах. Просто проверьте ещё раз как вы храните число в регистрах и константе и сверьте порядок проверки.
Кстати, как вариант. Такие числа лучше хранить целиком. Тут на помощь приходят директивы препроцессора. Например, у вас есть число 56ADEAD7. Тогда объявить его можно так:
Код:
#define longlong 0x56ADEAD7
Где #define - директива препроцессора; longlong - имя объявленной константы; 0x56ADEAD7 - значение константы. А что бы взять отдельный байт отсюда, можно написать такой макрос, который записывается где нить вверху:
Код:
#definebyte(x,y) ((x >> (y*8)) & 0xFF)
Данный макрос вызывается так:
Код:
byte(x,y)
где x - константа; y - номер возвращаемого байта относительно младшего разряда начинаемого с 0. Теперь в коде можно написать что нить типа:
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс авг 07, 2011 18:02:17
Друг Кота
Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52 Сообщений: 4468 Откуда: Главный Улей России (Moscow)
Рейтинг сообщения:0
Да проще простого. Сначала надо занести число, которое будет у нас эталоном в массив.
Код:
ARRAY: .db SER0, SER1, SER2, BUT
Предположительно, наш буфер лежит в ОЗУ, в массиве buffer
Код:
.dseg buffer: .byte4
А код будет таким:
Код:
.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.
_________________ I am DX168B and this is my favourite forum on internet!
Сейчас этот форум просматривают: grayrat и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения