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

Обсуждаем контроллеры компании Atmel.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 708
Зарегистрирован: Пт ноя 30, 2007 14:40:44

Сообщение Серый_ »

1) А правильно ли я забираю/читаю двухбайтное из EEPROM? (tiny2313)
2) Т. к. физически двубайтных здесь нет (и адрес однобайтен и данные в общем то туда-сюда), то записывать надо в этой же последовательности? (писать Low, увеличить адрес, писать High)
Спойлер.def adr=r18
ldi adr,0 ;или ldi adr,(metka_v_eeprom)
;-------------------------------
ee_read: ;cli запрет прерываний делается выше на всю операцию с кнопкой
sbic EECR,eepe ;если сброшен то EEPROM готов и далее
rjmp ee_read ;иначе ждать здесь
out EEAR,adr ;отправить адрес
sbi EECR,eere ;Start Read
in r16,EEDR ;забрать данные L (лежат слева направо LL>HH)

ee_read_h: sbic EECR,eepe
rjmp ee_read_h
inc adr ;увеличить адрес
out EEAR,adr ;отправить
sbi EECR,eere ;Start Read
in r17,EEDR ;забрать данные H

ret ;выход (прерывания разрешатся выше)
;-------------------------------
;EEPROM
.eseg .dw 0xFFFF ;(LLHH)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15778
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Для EEPROM обязательного формата для многобайтовых величин нет.
Единственное условие - следовать выбранному правилу - или старшие байты затем младшие или как у Вас младшие а затем старшие.
И такой же порядок при извлечении.
Low или High относятся только к непосредственно загружаемым величинам.
Это если допустим требуется выполнить чего-то подобного:
6071 загрузить в EEPROM
тогда

загружаем начальный адрес ячейки ЕЕПРОМ (допустим 0)
LDI r16,low(6071)
out EEDR,r16
выполнить запись младшего байта
инкремент счетчика адреса в EEADRH:EEADRL
ldi r16,high(6071)
out EEDR,R16
выполнить запись старшего байта
инкремент счетчика адреса в EEADRH:EEADRL

а извлечение делается допустим в регистровую пару Хh:Xl

загружаем начальный адрес ячейки EEPROM (допустим 0)
читаем данные (в EEDR)
in Xl, EEDR
инкремент счетчика адреса в EEADRH:EEADRL
читаем данные (в EEDR)
in Xh, EEDR

Касательно директив DW/DB относительно EEPROM (загрузка фиксированной строки программатором из файла)...
Должны вроде правильно байты раскладывать - первым младший, вторым старший.
Но ... склероз...
:dont_know:
Реклама
akl
Друг Кота
Сообщения: 4470
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

[uquote="Серый_",url="/forum/viewtopic.php?p=3540326#p3540326"]...записывать надо в этой же последовательности? (писать Low, увеличить адрес, писать High)...[/uquote]Как загрузите так и считаете. Думаю, оформить чтение/запись подпрограммой логичнее. Для примера, загрузка R16...R19 в формате младший-старший, а R20...R23 в формате старший-младший
Спойлер

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

.INCLUDE "tn2313def.inc"

.ESEG
	.org	0x00
EE_BEGIN:
	.DW LWRD(2345678901),HWRD(2345678901)
	.DB BYTE4(2345678901),BYTE3(2345678901),BYTE2(2345678901),BYTE1(2345678901)
EE_END:

;*******************************
	.CSEG

	.ORG	$00
RESET:
	RJMP	START

	.ORG	$20
START:
	LDI	R16,$6F
	OUT	SPL,R16

	SER	R20
	OUT	DDRA,R20
	OUT	DDRB,R20
	OUT	DDRD,R20

	SBI	ACSR,ACD	; выключить аналоговый компаратор
;*************************************************
	LDI	ZH,0
	LDI	ZL,EE_BEGIN
	LDI	YH,0
	LDI	YL,16
;-------------------------------
	sbic EECR,eepe ;если сброшен то EEPROM готов и далее
	rjmp PC-1	 ;иначе ждать здесь
READ_EEPROM:
	RCALL	EEREAD
	ST	Y+,R0
	INC	ZL
	CPI	ZL,EE_END
	BRLO	READ_EEPROM
	OUT	EECR,ZH
	RJMP	PC
;ee_read: ;cli запрет прерываний делается выше на всю операцию с кнопкой
;sbic EECR,eepe ;если сброшен то EEPROM готов и далее
;rjmp ee_read ;иначе ждать здесь
;out EEAR,adr ;отправить адрес
;sbi EECR,eere ;Start Read
;in r16,EEDR ;забрать данные L (лежат слева направо LL>HH)

;ee_read_h: sbic EECR,eepe
;rjmp ee_read_h
;inc adr ;увеличить адрес
;out EEAR,adr ;отправить
;sbi EECR,eere ;Start Read
;in r17,EEDR ;забрать данные H

;ret ;выход (прерывания разрешатся выше)
;-------------------------------
EEREAD:
	OUT	EEAR,ZL
	SBI	EECR,EERE
	IN	R0,EEDR
	RET

.EXIT
Опытный кот
Аватара пользователя
Сообщения: 708
Зарегистрирован: Пт ноя 30, 2007 14:40:44

Сообщение Серый_ »

Ок, спс. Проворачивать что-то более сложное, с заценкой конечного адреса пока не понадобилось, но засейвил для примера. (akl, имхо метки PC-1 и PC не имеют "точек выхода"). Запустил свои варианты R/W вроде пока работают, вроде пока безглючно. И ещё вопрос о двухбайтном, в данном случае "по научному" нужно ставить "nop"?

sbiw x,1 ;минуснуть 1 из пары (выполнится за 2 такта)
nop ;(поэтому пустотакт перед отправкой куда-либо)
out ocr1AH,xH ;отправить
out ocr1AL,xL

Офф:
СпойлерИ сорян, ответившим = в карму плюсовать дают только 1 раз (и то через поиск пользователя), а поднятия рейтинга сообщения висят уже давно. :)
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

А nop то зачем?
Реклама
Опытный кот
Аватара пользователя
Сообщения: 708
Зарегистрирован: Пт ноя 30, 2007 14:40:44

Сообщение Серый_ »

Не готовые/полу готовые данные "потекут по трубам"...?
Реклама
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Не разу не замечал.
Опытный кот
Аватара пользователя
Сообщения: 708
Зарегистрирован: Пт ноя 30, 2007 14:40:44

Сообщение Серый_ »

А у меня случалось на похожем примере: опрос матричной клавиатуры, первая строка кнопок "активируется" нулём с порта "B0", через кнопку - нуль поступает на pinB5.

cbi portB,0 ;активировать строку кнопок (0 активный = нажато)
nop ;cbi происходит в 2 такта поэтому pin здесь заценивать рано
sbic pinB,5 ;кнопка 1 = 0? (зажата?)
rjmp b2 ;НЕТ, к следующей кнопке
;...или далее

Как результат при отсутствии "nop" не работали все первые кнопки в строках.
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

При вводе/выводе - да надо. Если клавиатура подключена через длинный шлейф, то может одного "nop" и не хватить.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

sbiw сама отработает за два такта и ничего не будет отложено "на потом". Там всё нормально.
А вот с кнопками у вас именно аппаратная беда - емкость входа, выставили значение и пройдёт сотни наносекунд пока оно установится, поэтому нужны какие-то задржки. Кстати когда плата загрязнится одного нопа может оказаться недостаточно - это потенциально проблемное место, работа которого зависит от "RACE CONDITION". Поэтому я делаю наоборот - сначала читаю кнопки с ПРЕДЫДУЩЕЙ линии, потом меняю линию опроса - к следующему такту(через 1-2мс) всё давно уже устаканится.
Контактная информация:
akl
Друг Кота
Сообщения: 4470
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Для "устаканивания" данных вместо NOPов обычно хватает

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

	CBI	PORTB,0
	RCALL	PAUSE_RET	; 7 тактов
	SBIC	PINB,5
;..............
;..............
;..............
	RET
;********************************
PAUSE_RET:
	RET
;********************************
Серый_ писал(а):в данном случае "по научному" нужно ставить "nop"?

sbiw x,1 ;минуснуть 1 из пары (выполнится за 2 такта)
nop ;(поэтому пустотакт перед отправкой куда-либо)
out ocr1AH,xH ;отправить
out ocr1AL,xL
NOP не нужен. Вот режим работы модуля сравнения имеет значение, т.к. OCR1 может принять данные не только напрямую, а ещё и защёлкнуться в буфере. Перенос содержимого буфера в OCR1 произойдет при выполнении условия режима работы.
Мудрый кот
Аватара пользователя
Сообщения: 1812
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Приветствую.

Коллеги, есть ли способ сдвинуть 4-байтовое число на 4 бита быстрее 16 тактов.
Для определённости пусть используются 4 старших регистра, а сдвиг вправо.
Сомнения терзают из-за наличия командочки swap...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Опытный кот
Аватара пользователя
Сообщения: 708
Зарегистрирован: Пт ноя 30, 2007 14:40:44

Сообщение Серый_ »

[uquote="akl",url="/forum/viewtopic.php?p=3541340#p3541340"]Для "устаканивания" данных вместо NOPов обычно хватает... PAUSE_RET:[/uquote]
В общем да, было так:
Спойлерsbi portB,0 ;деактивация 1-й строки
cbi portB,1 ;и сразу активация 2-й строки

Были ложные срабатывания в 1-ом столбце (по нажатию первых кнопок любой строки). Между данными командами вклинил:
rcall bl_zvon ;блокировка звона меж строк

bl_zvon:
nop
ret ;и того 3+1+4 такта
Ложных срабатываний не выдавил при всём желании. :) Что до "блокировки звона" по кнопке 2...3mS, то все последующие нажатия блокируются на 0,5сек. по таймеру (оно же отвечает и за "турбирование" кнопок).
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Перед применением swap нужно в текущем регистре на место младшего ниббла поместить младший ниббл старшего регистра. И уложиться в меньше 3-х тактов, т.е. в два или один. Хороша задачка.
Docendo discimus
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15778
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

[uquote="Kavka",url="/forum/viewtopic.php?p=3541422#p3541422"]Приветствую.

Коллеги, есть ли способ сдвинуть 4-байтовое число на 4 бита быстрее 16 тактов.
Для определённости пусть используются 4 старших регистра, а сдвиг вправо.
Сомнения терзают из-за наличия командочки swap...[/uquote]
Для одиночного байта
SWAP Rd - обмен тетрадами
и
XCH Z,Rd - для обмена только с ОЗУ по указателю в Z (но не во всех подгруппах МК и для АВРстудио 4.19 неведомое)
плюсиком макрос обмена между регистрами

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

.macro XCHRR
 EOR @0,@1
 EOR @1,@0
 EOR @0,@1
.endmacro
Если было б в наборе подобие
XCHD a,@Ri
как у mcs51 -возможно было бы проще.
Иначе макрос делать придется...
:dont_know:
Мудрый кот
Аватара пользователя
Сообщения: 1812
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

pyzhman, BOB51, как работает swap и про обмен xor-ом я знаю. Спасибо за напоминание. :tea:

[uquote="pyzhman",url="/forum/viewtopic.php?p=3541454#p3541454"]Хороша задачка.[/uquote]Да, есть такое. Решил, вот, поискать на просторах интернета, да людей поспрашивать прежде чем предпринять попытку изобрести велосипед.

PS: Что-то "велосипед" на swap-е меньше 17 тактов не выходит. Видать никак...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Модератор
Аватара пользователя
Сообщения: 19100
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

4 байта сдвинуть 4 раза и без swap займет 16 циклов (а не тактов).
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Друг Кота
Аватара пользователя
Сообщения: 15778
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

SWAP - быстрый обмен тетрадами.
(7-4) <-> (3-0) в текущем регистре меняются местами тетрады.
Использовался для скоростных преобразований в двоично-десятичной математике (Упакованный двоично-десятичный формат, ежли склероз не изменяет). Также удобен при формировании тетрадных цифирек под БИС с аппаратным дешифратором семисегментного кода.
На сегодня такие алгоритмы весьма редко применяются, ибо почти всюду используется табличный знакогенератор, да и быстродействие МК заметно возросло.
Из современных СБИС в которых возможно встретиться с режимом тетрадного дешифратора - MAX7219 к примеру.
8)
Мудрый кот
Аватара пользователя
Сообщения: 1812
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

[uquote="Starichok51",url="/forum/viewtopic.php?p=3542126#p3542126"]4 байта сдвинуть 4 раза и без swap займет 16 циклов (а не тактов).[/uquote]
Именно поэтому я и спрашивал про быстрее 16 циклов/тактов. :)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Родился
Сообщения: 6
Зарегистрирован: Сб июн 01, 2013 18:51:03

Сообщение 4epemyxa »

Если допускается получение результата в других регистрах и сдвиг не циклический, то можно быстрее 16-ти:

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

		ldi		r16,16    ;сдвиг на 4 
		mul		r31,r16
		movw	r4,r0
		mul		r30,r16
		mov		r3,r0
		or		r4,r1
		mul		r29,r16
		mov		r2,r0
		or		r3,r1
		mul		r28,r16
		or		r2,r1
Это вправо, результат в R5-R2
Ответить

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