Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

[uquote="ДядяВован",url="/forum/viewtopic.php?p=4612628#p4612628"]
shonty писал(а):lgt8f328Pdef.inc я взял из статьи
Могли бы Вы выложить этот файл?[/uquote]
Да, конечно, во вложении.
Реклама
Аватара пользователя
ДядяВован
Вымогатель припоя
Сообщения: 500
Зарегистрирован: Вс окт 25, 2020 22:13:25
Откуда: Смоленск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ДядяВован »

Спасибо!
Реклама
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Доброго времени :beer:
[uquote="BOB51",url="/forum/viewtopic.php?p=4612413#p4612413"]Таки печалька...
:roll:[/uquote]
Печалька в другом :)
В том, что нет нормальной документации и нет поддержки, а зарегистрироваться на китайских форумах проблематично.

Если неукоснительно следовать даташиту, то не всё может получиться :)

Наконец то разобрался с 32-х битной записью в EEPROM.
Во всех доступных даташитах чётко написано:
EEDR 寄存器用于8 位字节模式接口,E2PD0~3 用于32 位模式的读写操作;
Регистр EEDR используется для интерфейса 8-битного байтового режима, а E2PD0~3 используется для операций чтения и записи в 32-битном режиме;
Но оказалось, что вовсе и нет. Читается EEPROM (32-х битный)через E2PD0~3 без вопросов, но записать получится только первые 8 бит.
Несколько дней занимался с ним :facepalm: Решение нашлось в коде от сюда: https://github.com/wemos/Arduino_XI/blo ... EEPROM.cpp
Оказывается записывать нужно не через E2PD0~3 (как в даташите), а через EEDR, да ещё и с извращениями :)

Если теперь в коде, то так:
1. готовим адрес 32-х битной переменной. Адрес должен располагаться в битах [14:2]
Cдвиг влево нв 2 бита:
Спойлер

Код: Выделить всё

	ldi YL, BYTE1 (EE_adr_test)
	ldi YH, BYTE2 (EE_adr_test)
	lsl R28
	rol R29
	lsl R28
	rol R29
	call EEWrite32
2. процедура записи (через EEDR, как в коде с гитхаба):
Спойлер

Код: Выделить всё

EEWrite32:	
	clr R16
	out EEARL,	R16
	out EEDR,	R22
	inc R16
	out EEARL,	R16
	out EEDR,	R23
	inc R16
	out EEARL,	R16
	out EEDR,	R24
	inc R16
	out EEARL,	R16
	out EEDR,	R25

	out EEARH,YH		
	out EEARL,YL

	cli
	ldi R16, 0x44
	ldi R17, 0x42
	out EECR, R16
	out EECR, R17
	sei
	ret
3. процедура чтения (через E2PD0..3, это уже как в даташите)
Спойлер

Код: Выделить всё

EERead32:
	cli
	out EEARH,YH
	out EEARL,YL

	ldi R16, 0x41			; 0b_0100_0001
	out EECR, R16
	nop
	nop
	in R22, E2PD0
	in R23, E2PD1
	in R24, E2PD2
	in R25, E2PD3
	sei
	ret
И вроде как не нужно в этом чипе ждать окончания предыдущей записи, как в мегах:

Код: Выделить всё

	sbic EECR,EEPE
	rjmp PC-1
Я проделал подряд 3 записи без ожиданий EEPE:

Код: Выделить всё

	call EEWrite32
	call EEWrite32
	call EEWrite32
	call EERead32
прочиталось без ошибок..

Думаю, что есть ещё какие-то источники информации, так как по даташиту понять как сохранять 32 бита невозможно.

PS не занимался бы этим и прошёл мимо, но в проекте как раз нужен EEPROM и как раз в основном 16-ти и 32-х битные данные.

Всем творческих успехов :) :beer:
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Хм..
Ещё по EEPROM в LGT8f328P хочу добавить:
Пробовал записывать в EEPROM массив в цикле, так же в цикле увеличивая адреса командой adiw. Получилась ерунда :)
Думал по 4 байта резервировать нужно:

Код: Выделить всё

.ESEG
	var1:		.byte 4
	var2:		.byte 4
	var3:		.byte 4
	...
Оказалось, что 1 байт - это и есть 32 бита :)
Теперь так:

Код: Выделить всё

.ESEG
	var1:		.byte 1
	var2:		.byte 1
	var3:		.byte 1
	...
Задаём адреса по 1 байу, но в цикле к адресу прибавляем 4 байта.

Сорри если слегка не в тему темы :) , но asm же
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ДядяВован
Вымогатель припоя
Сообщения: 500
Зарегистрирован: Вс окт 25, 2020 22:13:25
Откуда: Смоленск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ДядяВован »

Не совсем понятно. В eseg адреса двух соседних byte 1 будут отличаться на четыре?
Реклама
Аватара пользователя
Eats
Потрогал лапой паяльник
Сообщения: 309
Зарегистрирован: Сб фев 18, 2023 21:51:01
Откуда: Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Eats »

[uquote="shonty",url="/forum/viewtopic.php?p=4613169#p4613169"]Задаём адреса по 1 байту, но в цикле к адресу прибавляем 4 байта.
Сорри если слегка не в тему[/uquote]Да в тему-то оно в тему, только зачем нужны такие извращения? Ну нету в ЛГТ епрома. Надо просто принять это как данность. А есть эмуляция епрома во флеши, от этого и такая чехарда с адресами. И если бы мне понадобился епром, то я бы для него припаял отдельную микросхему по и2с и хранил бы данные в ней, а не перешивал каждый раз флеш, ресурс которого меньше, чем у епрома. Но ваши исследования на эту тему похвальны, я бы на такое вряд ли бы решился (по указанной выше причине).

P.S.: а за lgt8f328Pdef.inc спасибо!!!
Всего доброго.
Евгений.
Реклама
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Eats писал(а): Но ваши исследования на эту тему похвальны, я бы на такое вряд ли бы решился
Имею наглость быть счастливым :))
Eats писал(а):P.S.: а за lgt8f328Pdef.inc спасибо!!!
Спасибо Юрию Ревичу :) , а я тольео перепостил.
Eats писал(а):И если бы мне понадобился епром, то я бы для него припаял отдельную микросхему по и2с и хранил бы данные в ней, а не перешивал каждый раз флеш, ресурс которого меньше, чем у епрома.
Дискуссий достаточно на эту тему :)) не буду спорить.

ДядяВован писал(а):Не совсем понятно. В eseg адреса двух соседних byte 1 будут отличаться на четыре?
Нет, отличаться будут на 1, но отправляться в EEAR (EEARH/EEARL) будут со сдвигом, то есть
1 byte - это 32 байта.., но..
там как раз путаница небольшая, просто её нужно осмыслить :)
Адрес передаётся на 32-битную запись/чтение со сдвигом на 2 бита, [14:2]
А на 8-ми битную запись/чтение [14:0]
Дальше на примере:
.ESEG
var1: .byte 1
0b0XXXXXXX XXXXXXxx

Тоесть, если нам нужно обратиться к 32-х битной переменной, то сдвигаем на <<2, а последние 2 бита оставляем нули;

Код: Выделить всё

	ldi YL, BYTE1 (var1)
	ldi YH, BYTE2 (var1)
	lsl R28
	rol R29
	lsl R28
	rol R29
; или даже макросом:
.MACRO EE_ADDRESS
	ldi YL, BYTE1 (@0)
	ldi YH, BYTE2 (@0)
	lsl R28
	rol R29
	lsl R28
	rol R29
.ENDMACRO
Если же обращаемся к 8-ми битной переменной, то сдвигаем на 2 бита, а последние 2 бита (значения 0, 1. 2, 3) у нас будут адресовать байт в 32-х байтах.
Вобщем младшие 2 бита нужны для 8-ми битной адресации внутри 32-х битного байта..

Как то так :) надеюсь не сильно запутал :)

Но 1 byte в .ESEG - это 32 бита

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

Код: Выделить всё

EE_FIRST_LOAD:
	ldi ZL, LOW		(EE_FIRST_LOAD_DATA *2)
	ldi ZH, HIGH	(EE_FIRST_LOAD_DATA *2)
	
	EE_ADDRESS (START_SETTINGS_EE)	
	clr XH

	ldi R18, 6				; 6 байт 32-х битных данных
ee_first_loop_2:
	ldi XL, 22				; загружаем адрес регистра R22
	ldi R17, 4				; 4 байта данных
ee_first_loop_1:
	lpm
	st X+, R0				; переместили из памяти программм сначала в R22+, потом R23, R24, R25
	adiw Z,1 
	dec R17
	brne ee_first_loop_1
	call EEWrite32
	adiw Y, 0x04			; увеличиваем адрес EEPROM на 4 байта
	dec R18
	brne ee_first_loop_2
adiw Y, 0x04 ; увеличиваем адрес EEPROM на 4 байта
Ну тут как бы увеличиваю на 1 сдвинутый на 2 бита. Выходит, что на 4
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Eats писал(а):adiw Y, 0x04 ; увеличиваем адрес EEPROM на 4 байта
Ну тут как бы увеличиваю на 1 сдвинутый на 2 бита. Выходит, что на 4
Вот, и в коде у себя исправил :)) , что бы быть уж совсем точным и не путаться какой адрес меняем:

Код: Выделить всё

	adiw Y, (1<<2)			; увеличиваем 32-х битный адрес EEPROM
Добавлено after 3 hours 47 minutes 38 seconds:
Доброго времени :beer:
Не надоел я вам со своим LGT? :)
А то я новенький, не в курсе местных правил :))

Добрался таки я сегодня и до uDSC :)
Одно могу сказать, чип радует.

Выполним 0xFFFF*0xFFFF

Код: Выделить всё

ldi R16, 0b1010_0000
out DSCR, R16					; включаем uDSC

ldi R25, high (0xFFFF)	; второй множитель
ldi R24, low (0xFFFF)	
ldi R23, high (0xFFFF)	; первый множитель
ldi R22, low (0xFFFF)

; заметьте, здесь вводим только младшие байты
; старшие вводятся автоматически:
out DSDX, r24
out DSDY, r22

ldi r20, 0b0100_0100			; настройка IR:	DA = DX * DY
out DSIR, r20

; заметьте, здесь выводим только младшие байты
; старшие выводятся автоматически:
in r22, DSAL
in r24, DSAH
на выходе:
R25 FF
R24 FE
R23 00
R22 01

0xFFFE0001

:beer:

Добавлено after 2 hours 40 minutes 2 seconds:
и в довесок... :)
разделим 0x0FFFFFFFF на 0x1234
DA = DA/DY:

Код: Выделить всё

ldi R16, 0b1010_0000
out DSCR, R16					; включаем uDSC

ldi R27, BYTE2	(0x1234)
ldi R26, BYTE1	(0x1234)
ldi R25, BYTE4 (0x0FFFFFFF)
ldi R24, BYTE3 (0x0FFFFFFF)
ldi R23, BYTE2 (0x0FFFFFFF)
ldi R22, BYTE1 (0x0FFFFFFF)

out DSAH, R24
out DSAL, R22
out DSDY, R26

ldi r20, 0b10110000			; настройка IR: DA = DA/DY
out DSIR, r20

   sbis DSCR,D1				; ожидаем окончания деления
   rjmp PC-1

in r22, DSAL
in r24, DSAH
результат 0x0000E104

не нашёл только максимальное значение делимого, поэтому 0x0FFFFFFF старший разряд в 0 поставил, иначе ошибки.

Всем творческих успехов :beer:
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Starichok51 »

ты делишь 4 байта на 2 байта и ответ должен быть тоже 2 байта.
максимальное значение двух байтов равно 0xFFFF.
умножь делитель 0x1234 на 0xFFFF, и получишь максимальное значение для делителя 0x1234.
а вообще, для каждого делителя будет разное максимальное значение.

Добавлено after 6 minutes 52 seconds:
а если ты захочешь поделить на 0x0012, то тебе в делимом понадобится еще нулей добавить.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Starichok51 писал(а):умножь делитель 0x1234 на 0xFFFF, и получишь максимальное значение для делителя 0x1234.
Может я не понятно выразился:
shonty писал(а):не нашёл только максимальное значение делимого, поэтому 0x0FFFFFFF старший разряд в 0 поставил, иначе ошибки.
НО: если аппаратно делить 0xFFFFFFFF хоть на 0x1234, хоть на 0x5678 - результат получается 0x00000000.
Т.е. есть какое-то ограничение на максимальное значение делимого..
Полистал ДШ, но ничего толком не нашёл..
Пока оставил так, и думаю вряд ли мне понадобится в ближайшем будущем делить полные 32 бита.
СпойлерА здесь я просто выразил свой восторг от этого чипа :)
Потому что в реале меня никто не поймёт, да ещё и дурку вызовут :))) :)))
Шутка))
Творческих :beer:
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Starichok51 »

shonty, ты не в состоянии прочитать, что я тебе написал?
тогда повторю еще раз.
умножь делитель 0x1234 на 0xFFFF, и получишь максимальное значение для делителя 0x1234.
а вообще, для каждого делителя будет разное максимальное значение.

ладно, умножу за тебя.
0x1234 х 0xFFFF = 0х1233EDCC
любое число больше, чем 0х1233EDCC, при делении на 0x1234 даст переполнение результата и ты получишь ноль в ответе.
а 0x0012х 0xFFFF = 0х0011FFEE.
любое число больше, чем 0х0011FFEE, при делении на 0x0012 даст переполнение результата и ты получишь ноль в ответе.
может, теперь ты поймешь, что для каждого делителя будет разное максимальное значение.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Starichok51 писал(а):shonty, ты не в состоянии прочитать, что я тебе написал?
тогда повторю еще раз.
Зачем мне читать, что Вы написали, если Вы понятия не имеете о чипе.
Сейчас ещё раз разделил в программе 0xFFFFFFFF / 0x0012 = 0x00000000
а потом разделил 0x0FFFFFFF / 0X0012 = 0x00E38E38
(фото вывода на TFT дисплей могу сделать)
Starichok51 писал(а):а 0x0012х 0xFFFF = 0х0011FFEE
любое число больше, чем 0х0011FFEE, при делении на 0x0012 даст переполнение результата и ты получишь ноль в ответе.
Таки вот, моё делимое в железе 0x0FFFFFFF почему-то больше Вашего виртуального 0х0011FFEE.

Как так то? :shock: :shock:
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Starichok51 »

ну да, я понятия не имеете о чипе.
просто я не ожидал, что деление 32 бита на 16 бит может дать 32-битный результат. лично по мне, это противоречит логике.
больше не буду давать комментарии о неизвестном мне чипе.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Там не противоречия, просто так аппаратно выполненно:
[uquote="shonty",url="/forum/viewtopic.php?p=4613610#p4613610"]ldi r20, 0b10110000 ; настройка IR: DA = DA/DY
out DSIR, r20[/uquote]
DA = DA/DY
32-х битный DA делим на 16 битный DY, результат помещается в 32-х битный DA

Но с самой старшей тетрадой нужно потом разобраться.. Сейчас уже некогда.. И так много времени отдал "исследованиям".
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

shonty писал(а):Но с самой старшей тетрадой нужно потом разобраться..
Ещё раз посмотрел аппаратное деление. Делил на 0xFFFF.
Установка старших разрядов может давать ошибку, взависимости от велечины делителя.
Так если 0x0FFF_FFFF делить на 0xFFFF, то аппаратно результат 0x100E, хотя должен быть 0x1000.
Без ошибок на 0xFFFFаппаратно делится 0x00FF_FFFF и меньше.

Но опять же, зависит от делителя, если делить на 1, то и 0xFFFF_FFFF без ошибок делится. Вобщем нужно учитывать, что установка старшего байта, или отдельных бит в старшем байте, может выдавать ошибку.

Думаю, это не так существенно, так как аппаратное деление и так является приятным бонусом, просто нужно учитывать диапазон данных. Причём в чипе аппаратно заложен ещё ряд математическтх операций, включая сдвиги на N.
Но.. всё нужно проверять на крайних пределах :) так как в документации ничего не сказано об этом.

Творческих :beer:
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15575
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

Обычная математика, включая знаковые величины и ... "деление не 0"...
:roll:
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

[uquote="BOB51",url="/forum/viewtopic.php?p=4614010#p4614010"]Обычная математика, включая знаковые величины и ... "деление не 0"...
:roll:[/uquote]
Прошу прощения :oops: , наошибался в коде с подстановкой. Сейчас перепроверил ещё раз, на 0xFFFF делит как положено до 0x7FFF_FFFF.
а 0x8FFF_FFFF и выше это уже знаковое.
в железе: 0x8FFF_FFFF / 0xFFFF = 0x0000_7000 (такое значение в регистре DSA)
Старший бит - знак.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Starichok51 »

ладно, всё же напишу.
если бы старший бит был бы знаком, то выражение 0x8FFF_FFFF / 0xFFFF без знака превратилось бы в 0x0FFF_FFFF / 0xFFFF, и результат был бы 0х1000, а не 0х7000.
все равно какая-то непонятная ерунда с этим делением в этом чипе...
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение shonty »

Starichok51 писал(а):если бы старший бит был бы знаком, то выражение 0x8FFF_FFFF / 0xFFFF без знака превратилось бы в 0x0FFF_FFFF / 0xFFFF, и результат был бы 0х1000, а не 0х7000.
все равно какая-то непонятная ерунда с этим делением в этом чипе...
Согласен, и много чего не дописано.
На знаковые числа регистр IR настраивается при умножении.Например:
Изображение

"2" - это сноска

Изображение

S1 - знаковое DX, а S1 - знаковое DY, а что такое S0 в этой строке - история умалчивает..

А по делению такие настройки:

Изображение

Не сказано про знаковые.

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

А так то чип неплохой, использовать можно.. что я и пытаюсь делать :)

Добавлено after 9 minutes:
PS: Как только 15-й бит в делимом нарисовывается, так всё идёт непонятно как:
0x8FFF_FFFF / 0x0001 = 0x7000_0001 - это в железе

Просто учитывать это нужно..

На этом думаю сюрпризы не закончились :)
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Starichok51 »

а ты не пробовал скопировать иероглифы и вставить я Яндекс.Переводчик?
я для некоторых чипов делал такое - копировал китайский текст в даташите и переводил.
вообще-то, 8 дает 31-й бит, а не 15-ый.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Ответить

Вернуться в «AVR»