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

Обсуждаем контроллеры компании Atmel.
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

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

Сообщение dgrett »

ARV, Ваша память всё ещё на высоте :). Просто дописывала ноль до чётного и при компиляции выбрасывала жёлтый варнинг.
Я всё-всё узнAю и стану профессором.
Реклама
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

Да, так как адресация двухбайтная, компилятор об этом предупреждает, и дописывает недостающий байт нулем. Поэтому, кол во байтов всегда должно быть четным, дописывайте сами недостающий байт.
Реклама
С.Н.
Потрогал лапой паяльник
Сообщения: 307
Зарегистрирован: Пн окт 26, 2020 08:37:51
Откуда: г.Волгоград

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

Сообщение С.Н. »

[uquote="a1000",url="/forum/viewtopic.php?p=4139418#p4139418"]....Как истинный извращенец пишу на ASM.
...Правильно в програмном флеше.[/uquote]
А вот так другой "извращенец" сделал бы...
Целая куча энергонезависимой памяти с однобайтовой организацией!!!

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

.include "m328pdef.inc"

.ESEG
.org 0
	.db   0xFC,0x84,0xDA,0xCE,0xA6,0x6E,0x7E,0xC4,0xFE,0xEE,0x00

.DSEG
.org 0x100

.CSEG
.org 0x00								
.def	A		= r16				
.def	B		= r17				

.Macro  xchg
	push	@0
	push	@1
	pop	@0
	pop	@1			
.EndMacro

.Macro	ldiw 
	ldi 	@0L,low(@1)
	ldi	@0H,High(@1)
.EndMacro

.Macro  WaitEEPE ;Ожидание флага готовности EEPE		
	sbic	EECR, EEPE        	
	rjmp	PC-1
.EndMacro

.Macro  fld	;fld	Reg,XYZ
	WaitEEPE
	out	EEARH,@1H
	out	EEARL,@1L
	nop
	nop
	sbi	EECR,EERE
	in	@0,EEDR
.EndMacro

.Macro  flds	;flds	Reg,Addr
	WaitEEPE
	ldi	@0,High(@1)
	out	EEARH,@0
	ldi	@0,Low(@1)
	out	EEARL,@0
	nop
	nop
	sbi	EECR,EERE
	in	@0,EEDR
.EndMacro

.Macro  fsts	;fsts	Addr,Reg
	push	r0
	mov	r0,@1
	flds	@1,@0
	cpse	r0,@1
	rcall	writebyte
	mov	@1,r0
	pop	r0
.EndMacro

.Macro  fst	;fst	XYZ,Reg
	push	r0
	fld	r0,@0
	xchg    r0,@1
	cpse	r0,@1
	rcall	writebyte
	pop	r0
.EndMacro

writebyte:
	cli
	WaitEEPE
	out	EEDR,r0
	sbi	EECR,EEMPE
	sbi	EECR,EEPE
	WaitEEPE
	sei
	ret

Reset:
	cli
	ldiw	X,RAMEND
	out	SPL,XL
	out	SPH,XH
.
.
	sei

Loop:   
;Далее просто вот так читать!	
	ldiw	Z,2
	fld	A,Z
;или так	
	flds	A,2
;Или просто вот так записать!	
	ldiw	Z,2
	ldi	A,0x56
	fst	Z,A
;или так	
	ldi	A,0x56
	fsts	0x2,A
	rjmp	Loop	
Одно НО! Макрос не инструкция и всякие пропуски sbrc(s) или sbic(s) или cpse не работают....Табличку искомую можно в обычную оперативку ОЗУ скопировать при старте если требуется быстрый доступ.
Последний раз редактировалось С.Н. Пн дек 13, 2021 16:51:08, всего редактировалось 4 раза.
ФУОЗ на платформе Ардуино: https://radiokot.ru/forum/viewtopic.php ... 6#p4366626
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

EEPROM для изменяемых данных. Параметры, настройки и прочее. Если данные константы, значит храним их во Flash памяти.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15580
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

У ЕЕПРОМки ресурс перезаписи меньше чем у флеша.
Ставить туда чего-то часто перезаписываемого без проверок невыгодно.
Для чтения констант - затраты времени заметно выше, чем при чтении константы из флэша.
:roll:
Реклама
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

[uquote="BOB51",url="/forum/viewtopic.php?p=4140825#p4140825"]У ЕЕПРОМки ресурс перезаписи меньше чем у флеша...[/uquote]
Наоборот. :)
СпойлерИзображение
Вложения
EEPROM10000_FLASH100000.png
(17.23 КБ) 221 скачивание
Реклама
С.Н.
Потрогал лапой паяльник
Сообщения: 307
Зарегистрирован: Пн окт 26, 2020 08:37:51
Откуда: г.Волгоград

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

Сообщение С.Н. »

[uquote="BOB51",url="/forum/viewtopic.php?p=4140825#p4140825"]У ЕЕПРОМки ресурс перезаписи меньше чем у флеша.
Ставить туда чего-то часто перезаписываемого без проверок невыгодно.
Для чтения констант - затраты времени заметно выше, чем при чтении константы из флэша.[/uquote]
По всем пунктам ЗА!. Поэтому проверка встроена при записи. Про время оговорку сделал.
Замечу, что речь зашла про "часы", "извращенец.... на ассемблере".
Так впадем же в этот "блуд" по полной! У меня есть еще в запасе: "технология" #define ... #ifdef и всякие логические выражения, укорачивающие код; операции с нецелыми константами. Все это превращает программу на ассемблере в водевиль.
Чтобы не было обид - сам я такой же "извращенец" - в смысле "любитель ассемблера", как и автор вопроса про выравнивание данных по словам - Да пусть его часы будут ходить всегда верно и красиво! :)
ФУОЗ на платформе Ардуино: https://radiokot.ru/forum/viewtopic.php ... 6#p4366626
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15580
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

akl
В документации все верно...
Однако на практике - уж довольно часто имеем "глюки" с повреждением содержимого интегрированной в кристалл ЕЕПРОМки...
:(
Аватара пользователя
GoldenAndy
Поставщик валерьянки для Кота
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA
Контактная информация:

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

Сообщение GoldenAndy »

BOB51, ну так или BOD включайте, или после работы с еепромкой положите в регистр EEARL/EEARH адрес неиспользуемой ячейки еепрома
Содержимое обычно портися когда выключается питание. МК в агонии как жидкий терминатор в домне - бросается во все стороны и делает непредсказуемые вещи.
в т. ч. и команду записи или стирания еепрома может инициировать. И запортит ту ячейку, адрес коей лежит в EEAR....
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

В программе, работающей с EEPROM обязательно использую

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

	OUT	EECR,ZERO	; на всякий случай
	SER	R16
	OUT	EEARH,R16	; 
	OUT	EEARL,R16	;задать заведомо некорректный адрес
Касательно камней, у которых EEPROM <=256 типа Mega48 обмен должен быть по корректному адресу.
Спойлер

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

;************************************************
; Запись в EEPROM
; ZH,ZL -адрес
; R_DATA- данные
;************************************************
EEWRITE:
	CLR	ZH
;	SBIC	EECR,EEPE
;	RJMP	EEWRITE

;	OUT     EEARH,ZH
	OUT     EEARL,ZL
	OUT     EEDR,R_DATA

	SBI     EECR,EEMPE
	SBI     EECR,EEPE
EEWWAIT:
	SBIC    EECR,EEPE
	RJMP    EEWWAIT

	OUT	EECR,ZERO	;!!!!!!!!!!!!!!

	RET
;************************************************
; Чтение из EEPROM
; ZH,ZL-адрес
; R_DATA-данные
;************************************************
EEREAD:
	CLR	ZH
;	SBIC	EECR,EEPE
;	RJMP	EEREAD

;	OUT     EEARH,ZH
	OUT     EEARL,ZL

	SBI     EECR,EERE

	IN      R_DATA,EEDR

	OUT	EECR,ZERO	;!!!!!!!!!!!!!!

	RET
;************************************************
Аватара пользователя
GoldenAndy
Поставщик валерьянки для Кота
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA
Контактная информация:

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

Сообщение GoldenAndy »

akl, да можно и корректный адрес задавать. Главное, что б ячейка неиспользуемая была.
Или выделить под такую ячейку явный адрес, или загонять в EEAR значение E2END.
Но это в случае батарейных устройств, где МК спит 99% времени и должен экономить батарейку.
В остальных случаях проще включить в фузах BOD - и агонии МК не будет. Но за это надо платить парой десятков микроамперов.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Аватара пользователя
a1000
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Вс окт 18, 2020 19:01:52
Откуда: Харьковская область

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

Сообщение a1000 »

Скоро сломаю голову. Ошибка где-то на поверхности, но понять не могу.
Работаем с часами DS3231. Работаем по I2C через прерывание. Для начала получаю только секунды, минуты и часы. Старт, отправку адреса часов и регистра, рестарт опускаю. Там всё работает. Сразу к получению данных. Этот вариант работает без вопросов. В оперативке по метке TIMME лежат все нужные данные
Спойлер//в Temp1 обработанное содержимое регистра TWSR
cpi Temp1, 0x40 // Если 0x40 - Пришли после посылки команды на чтение, просто выкинем
breq Secc // в регистр Ack, сказав, что готовы принимать от часов секунды

cpi Temp1, 0x50 // Если 0x50 - Байт принят, нам надо положить его в ОЗУ микроконтроллера
breq ByteRecive // причем сюда будем много раз входить, поэтому ответ Ack



ByteRecive:

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 0
rjmp Minn

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 1
rjmp Hourr

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 2
rjmp Stop


Secc: ; получение секунд
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00000001
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV ; Команда на считывание первого байта - секунды
rjmp Exit

Minn: ; сохранение секунд и получение минут

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME, temp3 ; положили в оперативку секунды
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00000010
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV ; Команда на считывание второго байта - минуты
rjmp Exit

Hourr: ; сохранение минут и получение часов

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+1, temp3 ; положили в оперативку минуты
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00000100
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV2 ; Команда на считывание третьего байта - часы
rjmp Exit

Stop: ; сохранение часов и отправка стоп


IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+2, temp3 ; положили в оперативку часы
RCALL IIC_STOP ; Отослали стоп
Теперь пробую получать ещё 4 регистра - день недели, дату, месяц, год.
Спойлерcpi Temp1, 0x40 // Если 0x40 - Пришли после посылки команды на чтение, просто выкинем
breq Secc // в регистр Ack, сказав, что готовы принимать от часов секунды

cpi Temp1, 0x50 // Если 0x50 - Байт принят, нам надо положить его в ОЗУ микроконтроллера
breq ByteRecive // причем сюда будем много раз входить, поэтому ответ Ack



ByteRecive:

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 0
rjmp Minn

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 1
rjmp Hourr

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 2
rjmp Weekk

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 4
rjmp Datee

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 5
rjmp Monthh

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 6
rjmp Yearr

lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
sbrc flags, 7
rjmp Stop


Secc: ; получение секунд
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00000001
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV ; Команда на считывание первого байта - секунды
rjmp Exit

Minn: ; сохранение секунд и получение минут

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME, temp3 ; положили в оперативку секунды
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00000010
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV ; Команда на считывание второго байта - минуты
rjmp Exit

Hourr: ; сохранение минут и получение часов

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+1, temp3 ; положили в оперативку минуты
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00000100
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV2 ; Команда на считывание третьего байта - часы
rjmp Exit

Weekk: ; сохранение часов и получение дня недели

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+2, temp3 ; положили в оперативку часы
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00010000
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV2 ; Команда на считывание четвёртого байта - день недели
rjmp Exit

Datee: ; сохранение дня недели и получение даты

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+3, temp3 ; положили в оперативку день недели
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b00100000
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV2 ; Команда на считывание пятого байта - даты
rjmp Exit

Monthh: ; сохранение даты и получение месяца

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+4, temp3 ; положили в оперативку дату
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b01000000
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV2 ; Команда на считывание шестого байта - месяца
rjmp Exit

Yearr: ; сохранение месяца и получение года

IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+5, temp3 ; положили в оперативку месяц
lds flags, FFLAGS+1 ; извлекаем флаги I2C из оперативки
andi flags, 0b00001000
ori flags, 0b10000000
sts FFLAGS+1, flags ; положили в оперативку флаг I2C
RCALL IIC_RCV2 ; Команда на считывание седьмого байта - года
rjmp Exit


Stop: ; сохранение года, отправка стоп и вывод данных


IN temp3,TWDR ; Забрали из регистра TWIDR
sts TIMME+6, temp3 ; положили в оперативку год
RCALL IIC_STOP ; Отослали стоп
И вот тут засада. Секунды, минуты и часы по прежнему корректные, а вот остальные 4 байта заполнены единицами. Подскажите, где я напартачил?
Это Спарта! В смысле, ассемблер. Все ручками.
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

1 - в симуляторе студии проверьте, в какой момент появляются единицы. I2C в симуляторе не проверить, потому создайте программные закладки.
2 - не обязательно каждый раз считывать данные. Достаточно при включении считать данные, потом опрашивать вывод IRQ кажется, который тикает каждую секунду. Ессно, нужно теперь самому проводить все вычисления. Прибавление секунд, минут, часов. Но так проще.
Аватара пользователя
GoldenAndy
Поставщик валерьянки для Кота
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA
Контактная информация:

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

Сообщение GoldenAndy »

a1000, вот честно, в такой закрученной "циклической" логике с кучей переходов, базируясь на flags, я до конца не отследил что и как работает.
Сделайте один цикл на 7 итераций и в нем просто читайте 7 байт данных, складывая их в память и инкрементируя указатель.
Чтение по i2c с точки зрения МК - достаточно медленное, но я не думаю, что у вас прям такой реалтаймовый проект, когда не сделать чтение 3231 на ожиданиях.
Плюсом такого цикла будет то, что установка всех режимов, регистров, флагов i2c будет в одном месте. Включая ACK для всех байтов, кроме последнего, и NACK для последнего.
И тогда вы не наступите на те грабли, которые я вижу на первый взгляд.

У вас во втором примере чтение секунд и минут выполняется макросом/подпрограммой IIC_RCV (RCALL IIC_RCV) - судя по всему, это чтение с флагом ACK.
А вот часы вы читаете макросом IIC_RCV2 - это чтение с NACK - последний байт.
После этого 3231 понимает, что от него уже ничего не ждут, и ничего не отдает. вот вам и 0xFF.
Кроме того, вы читаете день недели, число, месяц и год тем же макросом - IIC_RCV2 - без ACK.

Замените везде, кроме последнего байта (год) RCALL IIC_RCV2 на RCALL IIC_RCV
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Аватара пользователя
a1000
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Вс окт 18, 2020 19:01:52
Откуда: Харьковская область

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

Сообщение a1000 »

GoldenAndy, вы абсолютно правы. Совсем забыл про NACK, вот и скопировал не глядя. Спасибо за помощь, исправил, всё заработало.
Это Спарта! В смысле, ассемблер. Все ручками.
Аватара пользователя
главный колбасист
Это не хвост, это антенна
Сообщения: 1338
Зарегистрирован: Чт авг 21, 2014 11:11:48
Откуда: краснодарский край
Контактная информация:

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

Сообщение главный колбасист »

А почему у меня команда ld не работает в студио-симуляторе для tiny2313 ?
Ошибка компиляции,неправильный регистр. Регистр длинный r30,адрес
ячейки туда загружен и такой и сякой.Все равно ошибка.
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

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

Сообщение dgrett »

А адрес озу у Вас где? Всю строку пж покажите.
Я всё-всё узнAю и стану профессором.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15580
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

[uquote="главный колбасист",url="/forum/viewtopic.php?p=4154711#p4154711"]А почему у меня команда ld не работает в студио-симуляторе для tiny2313 ?
Ошибка компиляции,неправильный регистр. Регистр длинный r30,адрес
ячейки туда загружен и такой и сякой.Все равно ошибка.[/uquote]
Регистровая пара Zh:Zl она же R31:R30
Диапазон адресов для команд LD rd,Z , LDS rdZ+rel касается только ОЗУ (для тини2313 это 0х0000-0x00DF)
Для доступа к таблицам в ПЗУ используется группа команд LPM
8)
Аватара пользователя
главный колбасист
Это не хвост, это антенна
Сообщения: 1338
Зарегистрирован: Чт авг 21, 2014 11:11:48
Откуда: краснодарский край
Контактная информация:

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

Сообщение главный колбасист »

ldi r30,0xdf
ld r20,r30
Ну вот...
И вот.
C:\AVRStudio\belov\belov.asm(50): error: Invalid register
Аватара пользователя
a1000
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Вс окт 18, 2020 19:01:52
Откуда: Харьковская область

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

Сообщение a1000 »

Боюсь ошибиться, но по моему, LD работает только с регистровой парой. Попробуйте так

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

ldi r30,0xdf
clr r31
ld r20,Z
Это Спарта! В смысле, ассемблер. Все ручками.
Ответить

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