Страница 254 из 400

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

Добавлено: Чт май 07, 2015 13:20:35
ILYAUL
akl писал(а):А можно спросить, для какого камня(ей) работают конструкции типа

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

    sbi      TIFR1,OCF1A
;
;
    sbis   TIFR1,OCF1A
?
Atmega 164P и иже. Atmega48 и ... ATTiny2313-4313

Кстати , когда работа прерываниям - эти строки естественно не нужны.
И раздельчик такой есть в DS :
Register summary

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

Добавлено: Пт май 08, 2015 03:59:50
akl
Спасибо, Илья! Правда, уже сам нашёл такие ATmega. У ATtiny (12,13,2313,4313,24...84 и т.д.) такой возможности нет.

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

Добавлено: Пт май 08, 2015 08:24:27
ILYAUL
akl писал(а): У ATtiny (12,13,2313,4313,24...84 и т.д.) такой возможности нет.
Да , это попутал .

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

Добавлено: Чт май 21, 2015 19:20:54
VanyaSV
мяу)
почему в atmega128 не срабатывает команда sbr flags,(1<<clk)?

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

Добавлено: Пт май 22, 2015 04:37:06
akl
Думаю, ошибка в объявлении.

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

.def	flags=R16 ;R16...R31
.set	clk=0  ;0...7
	sbr	flags,exp2(clk)
	clr	flags
	sbr	flags,(1<<clk) ;установит в flags бит clk

.set	clk=0b00001110
	sbr	flags,clk  ; установит биты объявленные clk

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

Добавлено: Вс май 24, 2015 05:19:00
afz
Коллеги, как я понял, все метки, объявленные внутри макрокоманды - временные. А нет ли возможности сгенерить внутри макрокоманды постоянную метку? Чтобы она действовала не только внутри макрорасширения, но и в основном тексте?

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

Добавлено: Вс май 24, 2015 05:43:37
pyzhman
Тогда это будет подпрограмма.

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

Добавлено: Вс май 24, 2015 10:44:55
Jack_A
afz писал(а): все метки, объявленные внутри макрокоманды - временные. А нет ли возможности сгенерить внутри макрокоманды постоянную метку? Чтобы она действовала не только внутри макрорасширения, но и в основном тексте?
Ну а сам как думаешь ? Вызвал N раз макрос, получил N макрорасширений с N метками. Все они глобальные, причем адреса разные, а имя одно. :( ( Кстати, нет временных и постоянных, есть локальные и глобальные . Временная - это как : после того, как к ней обратились - она стирается ? :) ) .
Поставил метку пред макровызовом - она и будет глобальной, делов-то.
А вообще попытка rjmp внутрь чего-то ( неважно - подпрограммы, макрорасширения ) - это порочный стиль "через опу". Языки высокого уровня это не допускают, и правильно делают, но на ассемблере можно и выпендриться. Как говорится, в сумасшедшем доме и не такое делают.
Ничего личного. Просто мое убеждение, основанное на рекомендациях корифеев и 40 годах практики.

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

Добавлено: Пн май 25, 2015 06:48:29
afz
Jack_A писал(а): Ничего личного. Просто мое убеждение, основанное на рекомендациях корифеев и 40 годах практики.
Если эти 40 лет практики захватили Систему 360, ты должен помнить фиктивные секции - исключительно удобная фенечка. Вот я и собирался склепать нечто подобное. Увы.
( Кстати, нет временных и постоянных, есть локальные и глобальные . Временная - это как : после того, как к ней обратились - она стирается ? :) ) .
Опять же, если твои 40 лет практики захватили PDP-11 и наши ее клоны, то ты должен помнить, что в приличных системах глобальными называют метки, которые определены и/или используются в другом, отдельно транслированном модуле, а связь их происходит на этапе линковки. И вообще, решение для временных меток в Макро-11 близко к идеалу, хотя, на мой взгляд, лучший ассемблер всех времен и народов был все-таки у Системы-360, те же фиктивные секции - рулез немерянный, да и язык макрогенерации (средства условной трансляции, набор и работа с макропеременными и пр.) у Системы-360 на голову выше всех остальных.
А вообще попытка rjmp внутрь чего-то ( неважно - подпрограммы, макрорасширения ) - это порочный стиль "через опу".
Вот кусочек текста:
Спойлер

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

; R4 to HEX

; Вход: R4 - исходный байт
; Выход - два байта по X+
; Рабочий регистр - R18

HEX:
	add	r2,r4
	mov	r18,r4
	swap	r18
	rcall	hex1
	mov	r18,r4
HEX1:
	andi	r18,0x0F
	cpi	r18,10
	brlt	hex2
	subi	r18,('0'-'A'+10)
HEX2:
	subi	r18,0xD0	; -'0'
	st	x+,r18
	ret
Здесь кусочек начиная с метки hex1 работает дважды: сначала вызывается, как подпрограмма, а потом в естественном порядке, каждый раз возвращаясь на команду, следующую за rcall'ом ее вызвавшим: в первый раз - одной командой выше метки hex1, второй - в программу вызвавшую HEX. Альтернативой этому было бы вынесение HEX1 в отдельную и на фиг не нужную подпрограмму, цена вопроса, кроме общей ненужности этой подпрограммы, две команды - лишний RCALL для ее вызова во второй раз и лишний RET после второго вызова.

Этот прием был рекомендован в DEC-овских руководствах по программированию на Макро-11 и работает на любых машинках, где вдрес возврата после CALL'а сохраняется в стеке.

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

Добавлено: Пн май 25, 2015 08:48:37
ARV
я уже многое забыл, но по-моему у AVR-овского ассемблера метки внутри макросов остаются глобальными, а чтобы они были локальными, нужен какой-то особый синтаксис - то ли @1, то ли что-то похожее... проверьте, а то я и сам не уверен в том, что говорю - смутные воспоминания...

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

Добавлено: Пн май 25, 2015 11:42:26
afz
ARV писал(а):я уже многое забыл, но по-моему у AVR-овского ассемблера метки внутри макросов остаются глобальными, а чтобы они были локальными, нужен какой-то особый синтаксис - то ли @1, то ли что-то похожее... проверьте, а то я и сам не уверен в том, что говорю - смутные воспоминания...
Нет. @0,@1... - это параметры макровызова. А метки внутри макросов таки внутренние и вне макрорасширения конкретного макровызова не видны. Собственно, столкнувшись с этим я и поднял этот вопрос.

Проблема в следующем. Мне категорически не нравится рекомендованная производителями метода заполнения таблицы векторов. Я придумал свой вариант - подробно он описан в теме http://radiokot.ru/forum/viewtopic.php? ... 4&start=20, последнее сообщение, вкратце же - копипастим из даташита ассемблерный пример заполнения таблицы векторов, переделываем листинг примера в набор команд (r)jmp и размещаем его в начале .cseg, далее копипастим его второй раз и переделываем в набор меток (тех, на которые ссылались rjmp), это получится набор заглушек для неиспользуемых прерываний, после которого ставим reti или что-то диагностическое, вроде rjmp .-1. Естественно, комментарии и там, и там оставляем. Собрался использовать какое-то прерывание - скопипастил из этой таблицы в нужное место соответствующую строчку, в таблице ее закомментировал, и вперед, не забыть только подправить метку для ADC, если он есть.

Несколько раз применял это решение на 8-й Меге, все было прекрасно, пока не стал переносить один проект на Мегу-8515. Слегка накосячил при замене этих таблиц, долго искал ошибку и понял, что это решение не самое лучшее, хотя и много лучше рекомендованного. Тогда я решил воспользоваться макрокомандами, чтобы в тексте в начале .cseg поставить макрокоманду AVRStart, а в нужном месте - AVRUnusedVec, которая сгенерит метки для неиспользуемых прерываний (посредством .ifndef). Тогда при смене чипа достаточно будет заменить в начале .incude, вызывающий блок макрокоманд для соответствующего контроллера, и все. Сделал, не поленился, сочинил программулю для писюка, которая из листинга, скопированного из даташита, генерит этот набор макрокоманд, попробовал, и тут прилетела птица Обломинго - метки внутри макрорасширения строго локальные...

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

Добавлено: Пн май 25, 2015 11:57:20
Seriyvolk
afz писал(а):Мне категорически не нравится рекомендованная производителями метода заполнения таблицы векторов. Я придумал свой вариант
Всё придумано до нас. Таблица векторов представляет собой .inc/asm файл, индивидуальный для каждого типа контроллера. Подключается в начале программы. И никакой путаницы.
Где не нужно - заглушка RETI, где нужно - прыжок на обработчик. По мне, так самое удобное решение.
Спойлер

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

.CSEG

			.include "vectors.asm"	  ; Подключаем таблицу векторов прерывания
			.org	INT_VECTORS_SIZE  ; Конец таблицы прерываний

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

			.ORG 	0x0000			; Проц стартует с нуля, но дальше идут вектора 
			RJMP 	Reset			; прерываний, поэтому отсяюда сразу же прыгаем
									; на начало программы. На метку Reset


; Тут распологается таблица векторов важнейшая вещь. Если про нее забыть, то
; можно огрести такие неразрешимые глюки, что просто капец. Так что не забываем.
; я его тупо скопировал из файла m8def.inc и заменил все .equ на .org, а потом
; дописал везде команду RETI. На случай если прерывание вдруг вылезет, чтобы 
; вернулось туда же откуда прервалось. 


; ***** INTERRUPT VECTORS ************************************************
.org	INT0addr	; External Interrupt Request 0
RJMP Interrupt_0	
.org	INT1addr	; External Interrupt Request 1
RJMP Interrupt_1	
.org	PCI0addr	; Pin Change Interrupt Request 0
RETI	
.org	PCI1addr	; Pin Change Interrupt Request 1
RETI	
.org	PCI2addr	; Pin Change Interrupt Request 2
RJMP Pin_Change_Interrupt_2
.org	WDTaddr		; Watchdog Time-out Interrupt
RETI	
.org	OC2Aaddr	; Timer/Counter2 Compare Match A
RETI	
.org	OC2Baddr	; Timer/Counter2 Compare Match A
RETI	
.org	OVF2addr	; Timer/Counter2 Overflow
RETI	
.org	ICP1addr	; Timer/Counter1 Capture Event
RETI	
.org	OC1Aaddr	; Timer/Counter1 Compare Match A
RETI	
.org	OC1Baddr	; Timer/Counter1 Compare Match B
RETI	
.org	OVF1addr	; Timer/Counter1 Overflow
RETI	
.org	OC0Aaddr	; TimerCounter0 Compare Match A
RJMP	TimerCounter0_Compare_Match_A
.org	OC0Baddr	; TimerCounter0 Compare Match B
RJMP	TimerCounter0_Compare_Match_B	
.org	OVF0addr	; Timer/Couner0 Overflow
RJMP Timer_Couner0_Overflow
.org	SPIaddr		; SPI Serial Transfer Complete
RETI
.org	URXCaddr	; USART Rx Complete
RETI	
.org	UDREaddr	; USART, Data Register Empty
RETI	
.org	UTXCaddr	; USART Tx Complete
RETI	
.org	ADCCaddr	; ADC Conversion Complete
RJMP ADC_Complete	
.org	ERDYaddr	; EEPROM Ready	
RETI	
.org	ACIaddr		; Analog Comparator
RETI	
.org	TWIaddr		; Two-wire Serial Interface
RETI	
.org	SPMRaddr	; Store Program Memory Read	
RETI	

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

Добавлено: Пн май 25, 2015 12:47:43
afz
Seriyvolk писал(а): Всё придумано до нас. Таблица векторов представляет собой .inc/asm файл, индивидуальный для каждого типа контроллера. Подключается в начале программы. И никакой путаницы.
Где не нужно - заглушка RETI, где нужно - прыжок на обработчик. По мне, так самое удобное решение.
Спойлер

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

.CSEG

			.include "vectors.asm"	  ; Подключаем таблицу векторов прерывания
			.org	INT_VECTORS_SIZE  ; Конец таблицы прерываний

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

			.ORG 	0x0000			; Проц стартует с нуля, но дальше идут вектора 
			RJMP 	Reset			; прерываний, поэтому отсяюда сразу же прыгаем
									; на начало программы. На метку Reset


; Тут распологается таблица векторов важнейшая вещь. Если про нее забыть, то
; можно огрести такие неразрешимые глюки, что просто капец. Так что не забываем.
; я его тупо скопировал из файла m8def.inc и заменил все .equ на .org, а потом
; дописал везде команду RETI. На случай если прерывание вдруг вылезет, чтобы 
; вернулось туда же откуда прервалось. 
	
То есть такая же самоделка, что и предложил я. Только у меня более-менее универсальная, а здесь под каждый проект нужно клепать отдельную, у меня отдельная нужна только под каждый контроллер. Вот пример для Меги 8515 в исходном виде (без макрокоманд). Начинать новый проект - одно удовольствие, а вот переносить на другой камень - можно допустить ошибку, которую долго придется искать.
Спойлер

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

	.include <m8515def.h>

	rjmp	RESET 			; Reset Handler
	rjmp	EXT_INT0		; IRQ0 Handler
	rjmp	EXT_INT1		; IRQ1 Handler
	rjmp	TIM1_CAPT		; Timer1 Capture Handler
	rjmp	TIM1_COMPA		; Timer1 Compare A Handler
	rjmp	TIM1_COMPB		; Timer1 Compare B Handler
	rjmp	TIM1_OVF		; Timer1 Overflow Handler
	rjmp	TIM0_OVF		; Timer0 Overflow Handler
	rjmp	SPI_STC			; SPI Transfer Complete Handler
	rjmp	USART_RXC		; USART RX Complete Handler
	rjmp	USART_UDRE		; UDR0 Empty Handler
	rjmp	USART_TXC		; USART TX Complete Handler
	rjmp	ANA_COMP		; Analog Comparator Handler
	rjmp	EXT_INT2		; IRQ2 Handler
	rjmp	TIM0_COMP		; Timer0 Compare Handler
	rjmp	EE_RDY			; EEPROM Ready Handler
	rjmp	SPM_RDY			; Store Program memory Ready Handler


RESET:	ldi	r16,high(RAMEND)	; Main program start
	out	SPH,r16			; Set Stack Pointer to top of RAM
	ldi	r16,low(RAMEND)
	out	SPL,r16
	sei				; Enable interrupts

; Здесь пишем свою программу



;****************************************************************


; Заглушки для неиспользуемых прерываний
;	Если понадобится, скопировать строку отсюда и поместить в 
;	соответствующее место программы, а здесь ее закомментировать

EXT_INT0:		; IRQ0 Handler
EXT_INT1:		; IRQ1 Handler
TIM1_CAPT:		; Timer1 Capture Handler
TIM1_COMPA:		; Timer1 Compare A Handler
TIM1_COMPB:		; Timer1 Compare B Handler
TIM1_OVF:		; Timer1 Overflow Handler
TIM0_OVF:		; Timer0 Overflow Handler
SPI_STC:		; SPI Transfer Complete Handler
USART_RXC:		; USART RX Complete Handler
USART_UDRE:		; UDR0 Empty Handler
USART_TXC:		; USART TX Complete Handler
ANA_COMP:		; Analog Comparator Handler
EXT_INT2:		; IRQ2 Handler
TIM0_COMP:		; Timer0 Compare Handler
EE_RDY:			; EEPROM Ready Handler
SPM_RDY:		; Store Program memory Ready 

	reti	; При получении незапланированного 
		; прерывания молча выходим.
	; При нужде можно поставить ловушку типа RJMP *

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

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

Добавлено: Пн май 25, 2015 15:52:50
Seriyvolk
afz писал(а):Только у меня более-менее универсальная, а здесь под каждый проект нужно клепать отдельную
Зачем? Ты, видимо, нифига не понял. Второе окошко с кодом - это и есть содержание файла vectors.asm. Первое - сам код.
И вот у тебя есть несколько камней, с которыми работаешь. Для этих камней за 5 минут стряпаются нужные заготовки, которые потом методом Ctrl+С/Ctrl+V самого .inc/.asm (без разницы) файла подключаются к нужному проекту.
Вместо RETI пропсываешь путь к обработчику прерывания по мере написания кода.
А у тебя куча прыжков непонятно откуда и куда, а потом такая-же куча заглушек. Смотрится вырвиглазно и если
переносить на другой камень
то действительно очень легко
можно допустить ошибку, которую долго придется искать.

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

Добавлено: Пн май 25, 2015 19:54:29
ARV
вообще-то для векторов прерываний правильная практика - задавать адрес вектора директивой .org и указанием символьного имени соответствующего вектора - см. соответствующий inc-файл для вашего типа МК. в этом случае достаточно задавать только задействованные векторы, причем в любом порядке - ассемблер сам расставит их в нужном порядке, заодно не надо помнить о размере команды jmp. заодно может быть и экономия памяти за счет использования неиспользуемой части таблицы векторов под полезный код.

а то, что предлагаете вы в последних постах - это костыльки лакированные.

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

Добавлено: Пн май 25, 2015 21:58:51
Seriyvolk
Ну хоть лакированные, и то хорошо. :))

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

Добавлено: Пн май 25, 2015 22:02:34
Jack_A
ARV писал(а): заодно может быть и экономия памяти за счет использования неиспользуемой части таблицы векторов под полезный код.
Конечно, каждому - свое, но я бы так не делал. Экономия мизерная ( как сгоревшие лампочки - вместо поплавка в сливном бачке :) ) А гемору может добавить, если случайно :( инициализировалось одно из неиспользуемых прерываний, можем получить трудно уловимый глюк. Мне возразят - не должно быть случайной инициализации. Согласен, в отлаженной проге. А так к сырому исходнику еще добавлять потенциальный баго-генратор ...
Но, повторюсь : Jedem - das Seine.

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

Добавлено: Вт май 26, 2015 06:47:20
ARV
вы начитались детских страшных сказок про трудноуловимые глюки. если мы говорим про AVR studio (а мы ведь про этот ассемблер говорим, верно?), то никаких трудноуловимых глюков там в принципе быть не может - максимум две-три попытки запуска отладчика, чтобы все эти "глюки" выловить.

что касается "я бы так не делал", то отвечу так: каждый волен сам выбирать себе способ выстрелить в ногу... глюков с размером jmp на больших и маленьких МК гораздо больше встречается, и отловить их существенно сложнее, ибо в случае "случайного" возникновения незапланированного прерывания переход происходит на непредсказуемый адрес с неизвестным опкодом - вот тут и профессионал сильно задумается, чего там говорить о начинающем...

ну и последний аргумент: вы же слыхали про магические числа и их вред в программировании? так вот, фиксированные адреса - это магические числа. когда вы размещаете команды, надеясь на то, что они окажутся в нужных адресах - вы используете магию этих чисел. а когда вы указываете символьные имена нужных адресов - это уже правильная практика. и не ради экономии шести байт это следует делать, а ради порядка и спокойствия.

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

Добавлено: Вт май 26, 2015 08:36:12
afz
ARV писал(а):вообще-то для векторов прерываний правильная практика - задавать адрес вектора директивой .org и указанием символьного имени соответствующего вектора
Вот эта правильная практика мне, как раз и не нравится. В том числе и тем, что я или должен прописать руками каждый, вектор, причем не одной строчкой, или оставить потенциальный глюкодром для неотлаженной программы. Мой вариант предполагает чисто механические действия над листингом ассемблерного примера из даташита, легко поддающиеся "механизации", собственно, я уже сочинил соответствующую программу для писюка. Я, правда, надеялся сделать вторую часть в виде макрокоманды, но, раз нельзя, буду копипастить кусочек с закомментированными заглушками и .include для генерации заглушек для тех прерываний, которые не используются.

Вариант, который предлагает Seriyvolk тоже неплох, но там нужен большой объем ручной работы и, ИМХО, мой вариант таки нагляднее. Я считаю главной ценностью своего варианта именно наличие той самой таблицы заглушек. Все прерывания на виду, не нужно помнить метку из AVR-овского инклудника. Что это за прерывание, прописано в комментарии от AVR, скопипастил куда надо из этой таблицы один элемент вместе с комментарием, закомментировал оригинал (или, наоборот, раскомментировал копию, как я сейчас предполагаю делать), и вперед. Можно, конечно, сделать нечто подобное и из того кусочка инклудника, который описывает вектора, но там надо самому сочинять метки для переходов, а так вполне информативный набор меток любезно предоставлен авторами даташита (кроме метки ADC, которую я, обычно, подправляю до iADC).

Вообще, создается впечатление, что авторы АВР Студии ничего, кроме писюка не видели, все богатство идей, реализованных в ассемблерах до-писюшных времен осталось за бортом...

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

Добавлено: Вт май 26, 2015 08:40:02
ARV
успехов вам!

P.S. как бы в попытках выдумать порох непромокаемый вам не удалось выдумать порох непросыхающй :)))