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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15581
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

Последние три позиции в functions...
И вроде на виду и "не приметны"...
:?
Реклама
Аватара пользователя
Shuspano
Грызет канифоль
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

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

Сообщение Shuspano »

Ноль на конце хорошь тогда, когда DB-шка не включает его. А ведь она может включать его. Отсюда мораль: найти у DB-шки конец надо другим способом.
Предполагаю так:

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

read_loop:
ldi counter, 2*(endstring-string) 
ldi ZL, low(2*string)
ldi ZH, high(2*string)
again:
lpm temp, Z+
rcall something
dec counter
tst counter
breq exit
rjmp again
Но че-то оно не работает. А из-за 16-битной авр-овской памяти, не могу догнать как правильно.

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

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

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

[uquote="Shuspano",url="/forum/viewtopic.php?p=4346131#p4346131"]Ноль на конце хорошь тогда, когда DB-шка не включает его. А ведь она может включать его. Отсюда мораль: найти у DB-шки конец надо другим способом.
.....Но че-то оно не работает. А из-за 16-битной авр-овской памяти, не могу догнать как правильно.
С AVRASM у меня все плохо, т.к linux[/uquote]
А чем мой код то не понравился?
Вы думаете компилятор в конец строки какой то другой НОЛЬ подставит? Да, будет два ноля, но программа то все равно на первый сработает.
Причину "не работы" Вашей программы тяжело обнаружить не имея представления кто заполняет string и куда потом он идет. Ну на первый взгляд - Ваш регистр counter всегда ноль по выходу из Вашего цикла.
Присмотритесь к своей задаче и выберите себе один из форматов string - или "0 terminated" или (устаревший)с длиной строки в первом байте строки.
ФУОЗ на платформе Ардуино: https://radiokot.ru/forum/viewtopic.php ... 6#p4366626
ВК - "ФУОЗ на микроконтроллере Atmega328P (МПСЗ)"
Аватара пользователя
Starichok51
Модератор
Сообщения: 19054
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

Shuspano писал(а):dec counter
dec counter
tst counter
breq exit
rjmp again
tst counter - лишняя команда. после декремента уже тест сделан.
и должно быть так:
dec counter
brne again
exit:

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

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

Сообщение BOB51 »

При текстовой строке, содержащей коды символов ASCII нужно только начальный адрес да контроль считанных данных на код 0х00.
Память читаем побайтово от начального адреса до встречи кода 0х00.
Или ищем иной код, используемый в качестве стопового, если это не символьная строка, а бинарник.
:roll:
Вопрос резервирования места под строку актуален только для ОЗУ (или ЕЕПРОМ).
8)
Реклама
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Практикую ставить метки в начале и в конце таблицы. К примеру

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

read_loop:
	ldi ZL,low(2*TBI)			;string)
	ldi ZH,high(2*TBI)			;string)
again:
	lpm R0, Z
	rcall something
	CPI	ZL,LOW(2*TBI_END)
	BRLO	AGAIN
EXIT:
	RJMP	PC

something:
	ST	Z+,R0
	RET
;*****
.org	$100
TBI:
		.DB	$3F,$06         ; 0,1 Кодирования индикатора 
		.DB	$5B,$4F		; 2,3
		.DB	$66,$6D		; 4,5
		.DB	$7D,$07		; 6,7
		.DB	$7F,$6F		; 8,9

		.DB	$00,$00		; гашение незначащего нуля
TBI_END:
;************************************************
С наступающим...
Реклама
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

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

Сообщение shonty »

[uquote="akl",url="/forum/viewtopic.php?p=4346287#p4346287"]С наступающим...[/uquote]Спасибо :)

Ну раз моё сообщение первое в этом году :), то ползвольте сначала всех поздравить :)
С новым 2023-м годом уважаемые форумчане!

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

Сначала грузил типа:

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

.set Var1 = 0x6EF5
ldi R16, low (Var1)
ldi R17, high  (Var1)
clr R18
в различных вариациях.
Потом после недолгих экспериментов пришёл к такому варианту:

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

.set Var1 = 0x28
ldi R20, BYTE1	(Var1)
ldi R21, BYTE2	(Var1)
ldi R22, BYTE3	(Var1)
причём вместо Var1 может быть любое значение до 32 бит (но потребуется 4-й регистр) Код конечно стал на много симпатичнее и нагляднее.

Но самое интересное, что во всей документации по авр асму, которой располагаю (от атмел и микрочип), ни где в функциях не нашёл "BYTE1", хотя написано что "BYTE2" и "HIGH" дублируют друг друга.. Может конечно в каких то старых мануалах есть. :dont_know:

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

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

Сообщение BOB51 »

Все прекрасно описано еще для avrsam2 для аврстудио4 (правда мой экземпляр уже в редакции от микрощипа)
40001917A_AVR Assembler_User Guides.pdf
(312.32 КБ) 148 скачиваний
смотреть страницу33...
или тот же встроенный help -> avr tools user guide -> avr assembler -> user's guide -> expressions (для авр студио 4.19)
За byte1 видимо просто не сочли нужным делать описание его эквивалента low.
Кстати... есть и альтернатива:

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

.set tests = 0x4567af
ldi r16,low(tests)
ldi r17,low(tests>>8)
ldi r18,low(tests>>16)
:beer:
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

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

Сообщение shonty »

BOB51 писал(а):За byte1 видимо просто не сочли нужным делать описание его эквивалента low.
Ага, и по этому пришлось догадываться по смыслу :)) у меня не так много фудаментальных знаний.
Я кстати тем же документом от микрочипа пользовался.
BOB51 писал(а):Кстати... есть и альтернатива:
Код:
.set tests = 0x4567af
ldi r16,low(tests)
ldi r17,low(tests>>8)
ldi r18,low(tests>>16)
Оо.. А за это спасибо. Тут можно больше 32 бит данных загрузить.
:beer:

Добавлено after 56 minutes 14 seconds:
[uquote="shonty",url="/forum/viewtopic.php?p=4394904#p4394904"]Ага, и по этому пришлось догадываться по смыслу :))...[/uquote] Ан нет, нашёл "BYTE1", в атмеловском "AVR Instruction Set Manual", вскользь упоминается всего в одном месте и то в примере.
п 57.2., стр. 90, (Atmel-0856L-AVR-Instruction-Set-Manual_Other-11/2016)

Но кстати я как то BYTE1,2,3.. лучше воспринимаю, чем low/high. И код ровнее :))
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

[uquote="shonty",url="/forum/viewtopic.php?p=4394904#p4394904"]...Тут можно больше 32 бит данных загрузить...[/uquote]Касательно студии, поддерживающей 32-битные значения, не получится. Я не смог выразить константу, кроме как прямым занесением

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

.equ	VAR	=1000000000000	;E8 D4A5 1000
Буду признателен тому, кто знает как это делается.
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

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

Сообщение shonty »

akl писал(а):Касательно студии, поддерживающей 32-битные значения, не получится.
В смысле? Только сейчас попробовал. Собирается без ошибок.
Студия 4.19, но в ней только собираю, а код пишу в стороннем редакторе.

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

.equ var = 999999999999999999999999999999999999999

ldi R16, low(var)
ldi R17, low(var>>8)
ldi R18, low(var>>16)
ldi R19, low(var>>24)
ldi R20, low(var>>32)
ldi R21, low(var>>40)
ldi R22, low(var>>48)
ldi R23, low(var>>56)
ldi R24, low(var>>64)
PS что в R24 не проверял, но думаю, что именно var>>64

Добавлено after 41 minute 51 second:
Хм.. да, действительно, больше 32 бит не получится.
Сейчас прогнал этот код, с выводом на дисплей.

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

.equ var = 77777777777777

ldi R16, low(var)
ldi R17, low(var>>8)
ldi R18, low(var>>16)
ldi R19, low(var>>24)
ldi R20, low(var>>32)
ldi R21, low(var>>40)
ldi R22, low(var>>48)
ldi R23, low(var>>56)
ldi R24, low(var>>64)
ldi R24, low(var>>72)

ldi YL,low (Result+9) 		; 
ldi YH,high (Result+9)		; 
	st  Y, R16
	st -Y, R17
	st -Y, R18
	st -Y, R19
	st -Y, R20
	st -Y, R21
	st -Y, R22
	st -Y, R23
	st -Y, R24
	st -Y, R25
Младшие 32 бита выводит правильно, а дальше или нули или мусор из FF, в зависимости от константы.

Изображение

а должно быть 46 BD 0C D0 DC 71
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

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

;.equ var = 999999999999999999999999999999999999999; калькулятор XP-винды с этим числом не справился, поэтому урезал до
.equ var = 9999999999999999999;8AC7230489E7FFFF

.CSEG
TEST:

ldi R16, low(var)
ldi R17, low(var>>8)
ldi R18, low(var>>16)
ldi R19, low(var>>24)
ldi R20, low(var>>32)
ldi R21, low(var>>40)
ldi R22, low(var>>48)
ldi R23, low(var>>56)
ldi R24, low(var>>64)

RJMP	TEST
.EXIT
:dont_know: Ничего похожего на 0x8AC7230489E7FFFF моя студия не собирает. Жирным выделено правильная часть значения.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15581
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

ДЫК....
Даже в СИ АВРок непосредственно задается максимум только четыре байта (long, double)
дальше уже float (но те же 4 байта).
Так что "особо не разгоняйтесь"
:beer:
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

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

Сообщение shonty »

Тут дело больше не в том, что бы преодолеть 4-х байтовый порог, а найти способ написания кода, что бы более менее воспринимался интуитивно.

Я на TFT дисплеи "подсел". Там, что бы задать координаты поля, нужно отправить 8 байт. Долго я не мог найти интуитивно понятный вариант. Пробовал и через макросы и через массивы под .db, но всё не то..
Вот только недавно попробовал использовать .dw, на нём и остановлюсь.
Но .dw имеет свои особенности, связанные с 16-ти битной организацией памяти. По этому в подпрограмме обработки есть небольшие заморочки :)) Хотя ни по циклам, ни по коду за рамки дозволенного не вышла. Ещё и регистры экономятся.

Теперь запись стала выглядеть примерно так:
Set_str_1_tab: .DW 3, 319, 20, 20+23
Смотрю и понимаю в каком углу дисплея это поле находится :))

А до этого постоянно в калькулятор приходилось нырять, что бы перегнать в такое: 0x00, 0x03, 0x01, 0x3F, 0x00, 0x14, 0x00, 0x2B :shock: ну или типа.

PS Тут ещё дело в значениях выше 0xff. Можно конечно в десятичном виде записывать: low(319), high(319), но это всё равно не изящно :))
Аватара пользователя
ДядяВован
Вымогатель припоя
Сообщения: 500
Зарегистрирован: Вс окт 25, 2020 22:13:25
Откуда: Смоленск

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

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

[uquote="Shuspano",url="/forum/viewtopic.php?p=4346131#p4346131"]С AVRASM у меня все плохо, т.к linux[/uquote]
gavrasm использую в linux, плюс avr_sim от того же автора.
AQ29
Прорезались зубы
Сообщения: 203
Зарегистрирован: Сб июл 30, 2011 21:00:24

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

Сообщение AQ29 »

[uquote="BOB51",url="/forum/viewtopic.php?p=4395088#p4395088"]ДЫК....
Даже в СИ АВРок непосредственно задается максимум только четыре байта (long, double)
дальше уже float (но те же 4 байта).
Так что "особо не разгоняйтесь"
:beer:[/uquote]
4 байта – маловато будет. В, условно говоря, хорошем ассемблере, в котором сейчас работаю, размер переменных до 8 байт. Работать намного удобней. И команды есть удобные.
Например, чтобы в примере shonty отправить через USART массив Set_str_1_tab, можно просто написать команду:
USART_Send_Array Set_str_1_tab Z
Z – указание, что в команде будет использоваться пара регистров Z.
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 545
Зарегистрирован: Ср июн 29, 2022 16:25:45

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

Сообщение Just_Fluffy »

AQ29, в ассемблере, какую обработку вы напишете, столько байт число и будет. Хоть 16. Хоть 32.
ПС. USART_Send_Array - не команда ассемблера, а макрос вашего алгоритм билдера, который асемблером называть не совсем корректно.
Белая и Пушистая
Я не ИИ, поэтому могу ошибаться.
AQ29
Прорезались зубы
Сообщения: 203
Зарегистрирован: Сб июл 30, 2011 21:00:24

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

Сообщение AQ29 »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4480077#p4480077"]AQ29, в ассемблере, какую обработку вы напишете, столько байт число и будет. Хоть 16. Хоть 32.
ПС. USART_Send_Array - не команда ассемблера, а макрос вашего алгоритм билдера, который асемблером называть не совсем корректно.[/uquote]
У меня не алгоритм билдер (АБ). Он давно устарел и сейчас явно слаб.
Ясно, что в командах ассемблера можно сделать разную обработку. Но с переменными работать многократно удобней, ведь для них для основных операций есть встроенные макросы, которые возьмут рутину на себя.
Когда при расчёте по сложной формуле переменная превысила 8 байт, менял алгоритм расчёта, чтобы остаться в пределах 8 байт.

Я не писал, что USART_Send_Array – команда ассемблера, у меня она названо просто командой.
В АБ нет встроенных команд такого типа. В АБ придётся самому писать макросы для всех вариантов команды, а их много.
Приведена неполная команда. В полном представлении команды есть ещё необязательные параметры: начальный индекс, с которого начнётся посылка массива, и число посылаемых элементов.
Есть ещё параметр Wait. При полудуплексной передаче после посылки пакета нельзя сразу переходить к приёму, надо подождать передачи последнего байта. Параметр Wait это делает.
Можно также указать номер USART, ведь в некоторых МК есть несколько USART.
Самому писать макросы под все эти варианты – тяжкий труд, это что-то из программирования прошлого века.
А со встроенными командами всё проще, достаточно только набрать строчку команды.
Насчёт некорректности названия ассемблер согласен. В этом плане предварительно сделал замечание «условно говоря». Программа находится где-то между ассемблером и ЯВУ. К ассемблеру всё-таки ближе.
chtulhu
Родился
Сообщения: 10
Зарегистрирован: Вс апр 21, 2019 13:04:18

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

Сообщение chtulhu »

Всем добрый день. Подскажите, как можно пробежаться по массиву, размещённому во флеш-памяти? Есть atmega8a. Написал такую программу, но она не работает

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

#define __SFR_OFFSET 0
	
#include	"avr/io.h"

	/* Секция данных */
	.section .data

table:
	.byte 0b00000001, 0b00000010, 0b00000011
	/* Секция кода */

	/*
1	0x000(1)	RESET	External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset
2	0x001	INT0	External Interrupt Request 0
3	0x002	INT1	External Interrupt Request 1
4	0x003	TIMER2 COMP	Timer/Counter2 Compare Match
5	0x004	TIMER2 OVF	Timer/Counter2 Overflow
6	0x005	TIMER1 CAPT	Timer/Counter1 Capture Event
7	0x006	TIMER1 COMPA	Timer/Counter1 Compare Match A
8	0x007	TIMER1 COMPB	Timer/Counter1 Compare Match B
9	0x008	TIMER1 OVF	Timer/Counter1 Overflow
10	0x009	TIMER0 OVF	Timer/Counter0 Overflow
11	0x00A	SPI, STC	Serial Transfer Complete
12	0x00B	USART, RXC	USART, Rx Complete
13	0x00C	USART, UDRE	USART Data Register Empty
14	0x00D	USART, TXC	USART, Tx Complete
15	0x00E	ADC	ADC Conversion Complete
16	0x00F	EE_RDY	EEPROM Ready
17	0x010	ANA_COMP	Analog Comparator
18	0x011	TWI	Two-wire Serial Interface
19	0x012	SPM_RDY	Store Program Memory Ready
	*/
	
	.section .text
	.org 0x0000
	
	rjmp RESET_vect
	reti	 		; INT0
	reti			; INT1
	reti			; TIMER2_COMP
	reti			; TIMER2_OVF
	reti			; TIMER1_CAPT
	reti			; TIMER1_COMPA
	reti			; TIMER1_COMPB
	reti			; TIMER1_OVF
	reti			; TIMER0_OVF
	reti			; SPI_STC
	reti			; USART_RXC
	reti			; USART_UDRE
	reti			; USART_TXC
	reti			; ADC
	reti			; EE_RDY
	reti			; ANA_COMP
	reti			; TWI
	reti			; SPM_RDY	
	
RESET_vect:
	ldi r16, RAMEND & 0xff
	out SPL, r16
	ldi r16, RAMEND >> 8
	out SPH, r16

	ldi r16, 0b00111111
	out DDRC, r16

	ldi r16, 0b00000000
	sei

_main:
	out PORTC, r16

	ldi ZL, lo8(table)
	ldi ZH, hi8(table)

	lsl ZH
	lsl ZL

	brcc _set_index
	inc ZH
	
_set_index:	
	ldi r17, 3
_loop:
	lpm r0, Z+
	out PORTC, r0

	dec r17
	cpi r17, 0x00
	brne _loop
	
	rjmp _main
Во всех примерах рекомендуют записать в Z регистр адрес массива, сдвинутый влево, но gnu assembler, как оказалось, не умеет применять операторы умножения и сдвига к адресам меток. Похоже, это связано с особенностями линковщика (по крайней мере, так пишут тут https://stackoverflow.com/questions/184 ... binary-and). Поэтому я поступил прямолинейнее и просто сдвинул ZL и ZH влево, а потом увеличил ZH, чтобы вернуть бит, потерянный при сдвиге. Но программа всё равно не работает и просто пишет 0xff в PORTC. Подскажите, в чём может быть ошибка?
Игорь_396
Встал на лапы
Сообщения: 102
Зарегистрирован: Ср дек 25, 2019 21:17:31
Откуда: Саратов

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

Сообщение Игорь_396 »

[uquote="chtulhu",url="/forum/viewtopic.php?p=4481822#p4481822"]просто сдвинул ZL и ZH влево,[/uquote]
А если так попробовать:
lsl ZL
rol ZH
Хз какой там синтаксис у GNU, в студии 4 обычно так пишу:
LDI ZH, High(Code_Table*2) ; адрес кодовой таблицы
LDI ZL, Low(Code_Table*2) ;

lpm ; данные в регистре 0
Ответить

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