Перейти к содержанию

Сложение Регистровой Пары (16Бит) И Рон (8Бит) - Ассемблер, Tiny2313


Microchip

Рекомендуемые сообщения

Здравствуйте.

Поставил тут меня в тупик один маленький вопросец:

Значит для использования в команде lpm нужно предварительно загнать в регистр Z нужный адрес.

Нужный адрес предполагается формировать из адреса таблицы и номера элемента этой таблицы.

Вопрос в том, как прибавить к регистровой паре Z восьмибитное число (num), хранящееся в каком-нибудь из РОН-ов.

Вот если бы я хранил адрес не в Z а в двух других РОН, вопросов у меня не возникло бы (команды add, затем adc).

Но как работает сложение в регистровой паре?

Может действовать также как и с разными РОН командами add и adc, но переносится ли бит переноса автоматом или нет в паре я инфы не нашел.

Конечно для 100% надежности можно поступить так: предварительно записать адрес в двух РОН, там произвести манипуляции над адресом, затем перенести побайтно в регистр Z. Но при этом тратится 2 "лишних" регистра.

Хотелось бы произвести сложение в самом регистре Z.

Будет ли работать этот код (строки 4...8):

использование таблицы в программе

1	 .def num = R16	 ; номер элемента в таблице
2	 .def data = R17 ; данные по номеру num из таблицы
		 ....
4	 ldi ZL, low(tab1*2) ; обращение к первой таблице по метке tab1 (умножаем на два чтобы перейти к побайтной адресации)
5	 ldi ZH, high(tab1*2)											
6	 add ZL, num	 ; прибавляем к адресу начала таблицы номер интересуемого элемента таблицы
7	 ldi temp, 0				
8	 adc ZH, ldi	 ; т.к. номер таблицы 8-ми битный то прибавляем ноль чтобы прибавился флаг переноса (если есть)

9	 lpm data, Z	 ; наконец достаем сами данные из таблицы

таблицы (в конце программного кода)

tab1: .dw <...сами данные...>
...
tabN: .dw <...данные...>

Изменено пользователем Microchip

Нет никакой заслуги тому, кто даёт золото, думая, что даёт камень (Будда)

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Ну раз никто не отвечает, отвечу (я с AVR не работал, но кое какие выводы можно сделать по коду):

У Вас указан тип данных в таблице - dw, а команда lpm передает 8ми-битные данные - т.е. читает побайтно. Уже несоответствие.

Умножение половинок адреса по отдельности на два тоже сомнительно - что будет, если младший байт например будет равняться 255 или там 200? (вобщем при условии ZL*2 > 255)... что сделает компилятор? Не знаю конечно что он сделает, но явно не сможет число более 255 записать в 8 бит, также как не догадается в старший байт перенести излишек. Вот тут можно об этом более-менее почитать:

http://forum.cxem.ne...showtopic=55775

Сложение 8 + 16 бит - судя по всему нужно на уровне 8-битных частей производить операции, и самостоятельно осуществлять перенос - вроде как Ваш кусок 6-8 должен работать по идее. Но вот на адресации будет затык скорее всего...

Встречный вопрос: а Вам проверить неначем? Или вслепую программу пишете? Т.е. без железки и эмулятора.... хех

Изменено пользователем tcoder
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Может действовать также как и с разными РОН командами add и adc, но переносится ли бит переноса автоматом или нет в паре я инфы не нашел.
Достаточно прочитать описание команд: add - сложение без учета бита переноса, сама команда выдает перенос, adc - сложение с учетом бита переноса, сама команда выдает перенос. Если интересно, с числами до 63 работает команда adiw (сложение регистровой пары X,Y,Z с числом). Вообще говоря регистры XL,XH,YL,YH,ZL,ZH это всего лишь другое название регистров r26,r27,r28,r29,r30,r31 так что с ними можно работать так же

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

ADIW складывает с константой. Автору нужно складывать с переменной, а это только через доп. регистр. Microchip, делайте через add и adc. Регистр Z 16-битный, значит вам нужно подготовить 16 бит для сложения. В R16 заносите значение смещения (8 бит), а в R17-0х00 (старший байт пустой). Далее все просто, младшие байты (Zl, R16) add Zl,R16, старшие байты (Zh, R17) - adc Zh,R17.

Ссылка на комментарий
Поделиться на другие сайты

Автору нужно складывать с переменной, а это только через доп. регистр
Смотря где она хранится. Если в регистровой паре то не нужно, если это один байт можно попробовать извратнуться с прыжками по проверке бита переноса.

Да, и в 8 строчке исходного кода ошибка, там очевидно не ldi а temp.

sbcc PC+2

inc ZH

nop

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Ошибка есть, это точно. Автор не указал какие конкретно данные собирается выбирать из массива. Если это строка, то, понятное дело, адрес на начало и инкрементом до конца строки. А если маска? Например, семисегментного кода и выборка значения случайная, зависящая от результата вычислений и значения в регистре. Суммировать с начальным адресом массива надо 16бит однозначно. Если регистр смещения 8-битный (до 256 элементов), то к нему надо взять в пару еще один временный регистр для старшего байта адреса и искусственно установить его в нулевое значение. Дальше обычное суммирование двух пар регистров (16бит+16бит) с учетом переноса. Если по листингу, то я бы не стал вставлять операцию присваивания LDI после выполнения сложения с младшим байтом регистровой пары Z. Хотя операция LDI и не влияет на флаги SREG, но такая "привычка" в других случаях может привести к потере флага переноса.

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

тут надо просто знать какие команды какие флаги используют. В частности ldi не использует бит переноса и помещать его между add и adc вполне можно. А строка... считывать побайтно, все равно по-другому нельзя а adiw Z,1 выполняется за один такт. Хотя ld temp,Z+ конечно красивее было бы, но это не из флеша а из ОЗУ.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

тут ничего сказать не могу, считывать данные из флеша не приходилось, специально для этого там есть SRAM и EEPROM.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Статические (неизменяемые) массивы с данными удобно держать во флеш и места достаточно, и переносить при включении не нужно.

Ссылка на комментарий
Поделиться на другие сайты

Была наконец-то написана пробная программулина, где я проверял несколько интересующих меня моментов.

Ура, чтение таблицы работает :) , чего не скажешь о моем коде вцелом :( .

Вот кусок:

;-------------- Декодер BCD в код сегментов ------------------
Dec7led:; подпрограмма принимает в temp число в BCD
; возвращает в этом же регистре семисегментный код
ldi ZL, low(tab7led*2) ; грузим младшее значение адреса таблицы циферь в ZL
ldi ZH, high(tab7led*2) ; старшее значение адреса таблицы циферь в ZH
add ZL, temp ; прибавляем к ZL номер нужной цифры (которую хотим лицезреть на индикаторе)
ldi temp, 0
adc ZH, temp ; + ноль в ZH с переносом
lpm temp, Z ; записываем семисегментный код из флеша в регистр temp
ret
;-------------------- Таблица циферь -------------------------
; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
tab7led:
.dw 0x7940, 0x3024, 0x1219, 0x7802, 0x1000
; 0-1, 2-3, 4-5, 6-7, 8-9

Перед вызовом подпрограммы Dec7led помещяем цифру в регистр temp, после возврата там будет число пригодное для вывода в порт на индикатор.

с директивой .dw есть нюанс: Таблицу размещаем 16-разрядными словами, но сначала идет старший байт.

Пример:

Берем первые цыфры таблицы "0" и "1".

Для индикации нуля согласно схеме нужно вывести число 01000000 (hgfedcba)

единицы - 01111001

Составляем из них шестнадцатиразрядное слово, но сперва цифра "1", затем "0"

01111001 + 01000000 --> 0b0111100101000000 или 0x7940

(читаться будет как надо - сперва "0", затем "1")

Следующие две цифры так же меняем местами, если число элементов нечетное, прописываем в последней паре нули в старшем байте (хотя по идее компилятор это должен сделать сам).

Все цыфры (0,1,...,9) отображаются корректно, так что можно пользоваться.

Нет никакой заслуги тому, кто даёт золото, думая, что даёт камень (Будда)

Ссылка на комментарий
Поделиться на другие сайты

Можно смело пользоваться директивой .db 0x40, 0x79, 0x24, 0x39 и т.д. Я таким алгоритмом и пользуюсь. Спасибо за предложенный кусок кода (он у меня уже давно используется).

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...