Да, когда равно и не только после выполнения этой команды.СКАЗОЧНИК писал(а):Флаг регистра SREG Z - устанавливается, в команде cpi, когда точно равно? Подразумеваю, что синонимы команд должны быть точны - (breq метка) и (brbs SREG_Z, метка).
Научите писать под AVR
- Реклама
Флаг Z полностью называется ZERO, т.е. НОЛЬ. И выставляется он, если в результате операции получился ноль. А CP/CPI/CPC по сути, выполняют вычитание своих операндов (как SUB/SUBI и др.), не изменяя самих регистров и не сохраняя результат действия (только его признаки в SREG). Следовательно если операнды равны, то из разность=0, и флаг Z станет "1".
Description:
Conditional relative branch. Tests the Zero flag (Z) and branches relatively to PC if Z is set. If the instruction is executed immediately after any of the instructions CP, CPI, SUB or SUBI, the branch will occur if and only if the unsigned or signed binary number represented in Rd was equal to the unsigned or signed binary number represented in Rr. This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). The parameter k is the offset from PC and is represented in two's complement form.
(Equivalent to instruction BRBS 1,k).
Если бы почитали встроенный хелп студии по команде BREQ, то увидели что так оно и естьСКАЗОЧНИК писал(а):Подразумеваю, что синонимы команд должны быть точны - (breq метка) и (brbs SREG_Z, метка).
Спойлер
BREQ - Branch if EqualDescription:
Conditional relative branch. Tests the Zero flag (Z) and branches relatively to PC if Z is set. If the instruction is executed immediately after any of the instructions CP, CPI, SUB or SUBI, the branch will occur if and only if the unsigned or signed binary number represented in Rd was equal to the unsigned or signed binary number represented in Rr. This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64). The parameter k is the offset from PC and is represented in two's complement form.
(Equivalent to instruction BRBS 1,k).
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Енто знаю. Как и С -флаг - Кери, N-флаг - Негатив и т.д. (вроде все простые аббревиатуры) .Engineer_Keen писал(а):Флаг Z полностью называется ZERO
И енто знаю. )))Engineer_Keen писал(а):не сохраняя результат действия (только его признаки в SREG)
Вот мне иной раз кажется, нафига придумали столько команд-синонимов.. ??? По моему с ними не удобства, а путаницы больше... Проще была бы одна универсальная, как выше указана и все бы знали про флаги... Хотя, с синонимами все равно флаги знать надо. Тогда смысл? Что лень после команды указать еще один оператор (или как их там)? Мне тяжело запомнить все "мнемоники" видов команд br**. Проще одну и логику работы флагов.Engineer_Keen писал(а):(Equivalent to instruction BRBS 1,k).
Станислав
А все и не надо. Чаще всего используются 4 BREQ BRNE BRCC BRCS. А остальное, когда понадобиться - можно подсмотреть в списке команд
Fucking static initialization order fiasco
- Реклама
Когда будете писать код на "большой" скорости (записать пока мысль не ушла!!!), поймете...СКАЗОЧНИК писал(а):Что лень после команды указать еще один оператор (или как их там)?
Все мнемоники вполне логично расшифровываются, поэтому проще как раз писать BRxx, зная что EQ - это равно, NE - не равно, GE - больше или равно, чем более абстрактные BS/BC. ИМХО конечно...СКАЗОЧНИК писал(а):Мне тяжело запомнить все "мнемоники" видов команд br**. Проще одну и логику работы флагов.
Спойлер
И вообще, я например, уже давно не пользуюсь этими командами, они все у меня задвинуты в макросы типа:Код: Выделить всё
.macro CJNE ;аналог из MCS-51
CPI @0,@1
BRNE @2
.endm
Код: Выделить всё
CJNE R16,1,L2
делаем что-то если R16=1
RJMP EXIT
L2:
CJNE R16,2,L3
делаем что-то если R16=2
RJMP EXIT
L3:
CJNE R16,2,EXIT
делаем что-то если R16=3
EXIT:RET
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Снова туплю... А есть такая команда, которая может перевернуть байт, точнее сделать логическое НЕ? Т.е. если было все нули, то стали все единицы. А потом снова заходим опять НЕ и стали снова все нули.. 
Станислав
COM ?
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Есть такая, в справочнике у меня не сильно понятное ее описание.. ( Ну или я тупой.
Спасибо!
Вот блин... Писал-писал программу... Даже ошибок нет при компиляции... ОДнако.... Как всегда... В железе неправильно работает...
Придется дебагить мой быдлокод.
Философия...
Спасибо!
Вот блин... Писал-писал программу... Даже ошибок нет при компиляции... ОДнако.... Как всегда... В железе неправильно работает...
Философия...
Станислав
По поведению флагов - сделай распечатку системы команд и руководствуся.
(dok0856 - Rev. 0856I–AVR–07/10)
Для работающего под ассемблером - обязательное настольное приложение!
Ну и еще разок добавка для разнообразия любителям ассемблера:
(dok0856 - Rev. 0856I–AVR–07/10)
Для работающего под ассемблером - обязательное настольное приложение!
Ну и еще разок добавка для разнообразия любителям ассемблера:
Станислав
Описание команд на русском есть в "Микроконтроллеры AVR семейства Tiny Mega фирмы Atmel" А.В.Евстифеев
Ну и чисто по АСМу: http://radiokot.ru/forum/download/file.php?id=192284
Ну и чисто по АСМу: http://radiokot.ru/forum/download/file.php?id=192284
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
У него вроде как простой машинный перевод даташита.... Даташит я могу и на агнлийском почитать. А вот команды, было бы интересно...Gudd-Head писал(а): А.В.Евстифеев
А эта штука у меня есть. )) И в распечатанном виде и в трех разных вариантах на компе... Просто ту, что я выше выложил ,там вообще все команды подробно с примерами расписаны и каждая команда на отдельный лист.Gudd-Head писал(а):Ну и чисто по АСМу
Станислав
А Вы, простите, туда хотя бы заглядывали, чтобы делать такие выводы? Было бы очень не плохо, если бы Яндекс с Гуглом умели так переводить, а заодно и обощать сведения из нескольких десятков даташитов..У него вроде как простой машинный перевод даташита
Так что же Вам мешает ей пользоваться? Плохой машинный перевод?А эта штука у меня есть.
Fucking static initialization order fiasco
Вот для примера оттуда страница.СКАЗОЧНИК писал(а):Просто ту, что я выше выложил ,там вообще все команды подробно с примерами расписаны и каждая команда на отдельный лист.
- Вложения
-
- Микроконтроллеры AVR семейства Tiny Mega фирмы Atmel А.В.Евстифеев 2005-600RM.djvu.pdf
- (42.57 КБ) 206 скачиваний
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Блин, красиво. ))) Признаю, был не прав. Значит как-то не так я Евстифеева смотрел...Gudd-Head писал(а):оттуда страница.
Станислав
Я вот тут набыдлокодил... (((( Сильно не пинайте.. Но не заполняет переменные нулми и единицами со сдвигом... В них все равно остаются только нули... И в итоге сравнение в конце с кодами (константами) не происходит...
Уже голову сломал. Толи переменная ТАЙМ не переносится из прерывания, где она заполняется, толи не работает сдвиг влево.... Может увидите где у меня в мозгах ошибка?
Блин, как корректно из АВРстудио вставить комментарии??
Код: Выделить всё
NULONE: ; Заполнение 4 переменных нулями и единицами с послыл
inc CNT ; Прибавляем единицу, всего надо досчитать от 1 до 32 (32 бита: адрес + комадна, последний бит игнорим)
cpi CNT, 32
brbs SREG_Z, END ; Если равно, то уходим в Энд
cpi TIME, 60 ; Сравниваем число тиков таймера с 60
brbs SREG_C, NUL ; Если меньше 60, то установится фалг переноса С. Тогда переходим в подпрограмму Нуля
sec ; Иначе, обрабатываем Единцу, устанавливаем флаг С
rol LCMD ; Задвигаем единицу в самый правый разряд
rol HCMD ; и по очереди сдвигаем все байты влево
rol LADR ; В итогде, вся цепочка переместилась влево на один бит, а старший вывалился...
rol HADR
ret ; Все, вышли .
NUL:
clc ; Убираем флаг С
rol LCMD ; Задвигаем ноль в самый правый разряд
rol HCMD ; и по очереди сдвигаем все байты влево
rol LADR ; В итогде, вся цепочка переместилась влево на один бит, а старший вывалился...
rol HADR
ret ; Все, вышли .
END:
clr FLAG
clr CNT
clr YYY
out TCCR0B, CNT ; Просто для экономии команд вместо Темп использовали КНТ(он все равно чистый)/ Остановили таймер
cpi HADR, 0b00100000
brbc SREG_Z, FINI
cpi LADR, 0b00100100
brbc SREG_Z, FINI
cpi HCMD, 0b00001110
brbc SREG_Z, FINI
cpi LCMD, 0b01101000
brbc SREG_Z, FINI
inc RUN
FINI:
retБлин, как корректно из АВРстудио вставить комментарии??
Последний раз редактировалось СКАЗОЧНИК Ср окт 15, 2014 17:34:21, всего редактировалось 1 раз.
Станислав
Ети?
Самое интересное, что все компилится нормально, и в дебагере гонял, тоже все устроило (ошибки поправил), потом в железо залил, еще несколько ошибок испраил... В итоге, Реагирует на пульт ИК, но только если все сравнения делать не с кодами команды, а с НУЛЯМИ.... Т.е. в четыре переменные не записывается информация...., они остаются пустые... Это значит где-то в этой процедуре ошибка, либо в прерывание по спадающему фронту, где включается таймер и считает время длительности импульса может быть косяк. О! Сейчас тоже проверю...
ВСЕ! НАШЕЛ! Пока вопросов больше нет! Спасибо.
Код: Выделить всё
.def temp = R16
.def TIME = R17
.def FLAG = R18
.def LADR = R19
.def HADR = R20
.def LCMD = R21
.def HCMD = R22
.def CNT = R23
.def RUN = R24
.def SCREEN = R25
.def OFF = R26
.def YYY = R27ВСЕ! НАШЕЛ! Пока вопросов больше нет! Спасибо.
Станислав
The falling edge of INT0 generates an interrupt request.
Вот это как переводится? Прерывание по спадающему фронту?
Вот, кое-чего добился. На пульт ИК уже реагирует... Однако не совсем так, как мне надо. При включении можно послать с пульта одну единственную команду, которая мне и нужна, он ее понимает и даже правильно расшифровывает и даже запускает двигатель, все как мне и нужно. Однако, снова эту же команду отказывается принимать... Или если первой командой нажать любую другую (при этом он не реагирует), то и потом не реагирует на ту, что мне надо.
Я так понял, что просто я проигнорил первую посылку (стартовый бит), поэтому и остальные команды для него становятся чушью. Поэтому решил стартовый бит вставить, чтобы он мог ориентироваться ,пора ловить команду или игнорить как помеху... В итоге, он вообще перестал определять мою нужную команду. Ни на что не реагирует.
Вот это как переводится? Прерывание по спадающему фронту?
Вот, кое-чего добился. На пульт ИК уже реагирует... Однако не совсем так, как мне надо. При включении можно послать с пульта одну единственную команду, которая мне и нужна, он ее понимает и даже правильно расшифровывает и даже запускает двигатель, все как мне и нужно. Однако, снова эту же команду отказывается принимать... Или если первой командой нажать любую другую (при этом он не реагирует), то и потом не реагирует на ту, что мне надо.
Я так понял, что просто я проигнорил первую посылку (стартовый бит), поэтому и остальные команды для него становятся чушью. Поэтому решил стартовый бит вставить, чтобы он мог ориентироваться ,пора ловить команду или игнорить как помеху... В итоге, он вообще перестал определять мою нужную команду. Ни на что не реагирует.
Код: Выделить всё
INT0add: // Прерывание срабатывает, когда на ТСОП приходит сигнал, т.е. по падению фронта.
PUSHF
// по переменной ФЛАГ определяем какой раз мы пришли в прерывание уже с начала получения послыки от ИК-пульта
cpi FLAG, 0 ; Проверяем флаг равен нулю или нет? Были мы раньше в прерывании или нет еще?
brbc SREG_Z, S1 ; Если не равен, то переходим по метке.
// А если мы еще не были в прерывании ни разу, то проверяем, СТАРТОВЫЙ бит или нет
clr temp // Запускаем таймер а измерение длины стартового импульса
out TCNT0, temp ; Первоначально очищаем счетный регистр раймера
ldi temp, (1<<CS02)|(0<<CS01)|(1<<CS00) ; Тактовый сигнал = CK/1024 (ЗАПУСКАЕМ ТАЙМЕР)
out TCCR0B, temp
inc FLAG ; Прибавляем единицу, флаг стал равен 1 (следующий этап определится уже, как "второй раз в прерывании"
POPF
reti ; Выходим из прерывания
S1: cpi FLAG, 1 ; Здесь прверяем опять, какое по счету прирывание.
brbc SREG_Z, S2 ; Если не равен, то переходим по метке (если прерывание не второй раз, значит уходим)
/=========================
/А вот это я всего лишь добавил... Если закомментировать, то будет работать (как писал выше) реагирует на пульт один раз, а если не комментировать, то не реагирует на пульт вообще..
in CNT, TCNT0 Здесь закидываем в перменную значение натиканного таймера после первого прерывания
clr temp
out TCCR0B, temp ;Тормозим таймер (он больше не нужен сейчас)
/ А теперь сравниваем полученное измерение с диапазоном значений. Значения такие потому что при частоте 9,6 МГц и предделителе на 1024 для СТАРТОВОЙ посылки, которая по протоколу равна 13,5 мс надо всего 126,5 тактов таймера. Взял с запасом в обе стороны, при этом значения все равно укладываются во все допустимые промежутки по протоколу NEC
cpi CNT, 122
brlo S3 ; Переход если меньше
cpi CNT, 130
brsh S3 ; Переход если болше или равно
/==========
/Ну а дальше, если СТАРТ попал в допустимое значеие, можно работать
clr temp
out TCNT0, temp ; Первоначально очищаем счетный регистр раймера
ldi temp, (1<<CS02)|(0<<CS01)|(0<<CS00) ; Тактовый сигнал = CK/256 (ЗАПУСКАЕМ ТАЙМЕР) Начинаем замеры импульсов посылки ИК
out TCCR0B, temp
inc FLAG ; Прибавляем еще единицу к флагу, флаг стал равен 2
POPF
reti
S2: cpi FLAG, 2 ; Проверяем флаг равен двум? Ага, мы уже считаем импульсы, значит только копируем значение и чистим таймер.
brbc SREG_Z, S3 ;
in TIME, TCNT0 ; Закидываем в Тайм значение счетчика, будем использовать его позже
ldi YYY, 1 ; переменная для определния, что пора переходить в обработку в главном цикле вызывается процедура
clr temp
out TCNT0, temp ; Чистим таймер, начинаем счет по чистой следующего импульса
POPF
reti
S3: clr FLAG ; Иначе, тупо чистим флаг и останавливаем таймер, чистим переменную
out TCCR0B, FLAG ; Просто для экономии команд вместо Темп использовали ФЛАГ (он все равно чистый)
clr TIME
POPF
retiСтанислав


