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

Обсуждаем контроллеры компании Atmel.
Ответить
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Сообщение ILYAUL »

А предделитель поменять нет? и Free timer c двумя прерываниями OCR
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

ILYAUL писал(а):Free timer c двумя прерываниями OCR
Эээ... Чаго? :shock:
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Сообщение ILYAUL »

Спойлер

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

;**************************************************
;*       	;;/Initialization TIMER1;;*   		  *
;**************************************************

		outi	OCR1BH,	high(7)
		outi	OCR1BL,low(7)
		ldi		temp,1<<OCIE1A|1<<OCIE1B
		outr	TIMSK1,temp
		ldi		temp,1<<CS11|1<<CS10
		outr	TCCR1B,temp 
;******************************************

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

;-Задержка на 40us(25кгц) для Xtal 110592MHz
;******************************************
Wait40us:
		sbi		TIFR1,OCF1A
		inr		temp,TCNT1L
		inr		temp1,TCNT1H
		subi	temp,(low(-6+1))
		sbci	temp1,(high(-6+1))
		outr	OCR1AH,temp1
		outr	OCR1AL,temp
		sbis	TIFR1,OCF1A
		rjmp	PC-1
		ret
;**************************************
;-		Задержка на 1,5ms              
;**************************************
Wait1_5ms:
		sbi		TIFR1,OCF1B
		inr		temp,TCNT1L
		inr		temp1,TCNT1H
		subi	temp,(low(-259+1))
		sbci	temp1,(high(-259+1))
		outr	OCR1BH,temp1
		outr	OCR1BL,temp
		sbis	TIFR1,OCF1B
		rjmp	PC-1
		ret
;**************************************
;- 			Задержка на 20 ms          
;**************************************
Wait20ms:
		sbi		TIFR1,OCF1A
		inr		temp,TCNT1L
		inr		temp1,TCNT1H
		subi	temp,(low(-3456+1))
		sbci	temp1,(high(-3456+1))
		outr	OCR1AH,temp1
		outr	OCR1AL,temp
		sbis	TIFR1,OCF1A
		rjmp	PC-1
		ret
Таймер крутится постоянно 0- FFFF (mode Normal) , ты ему только значения для OCRA-B подпихивай
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

А можно спросить, для какого камня(ей) работают конструкции типа

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

    sbi      TIFR1,OCF1A
;
;
    sbis   TIFR1,OCF1A
?
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

akl писал(а):А можно спросить, для какого камня(ей) работают конструкции типа
Подъебал :wink:
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Почему? Серьёзно.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

?
SBI-ки работают с младшими 32-мя регистрами, у Меги8 TIFR под номером 56.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Сообщение ILYAUL »

akl писал(а):А можно спросить, для какого камня(ей) работают конструкции типа

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

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

Кстати , когда работа прерываниям - эти строки естественно не нужны.
И раздельчик такой есть в DS :
Register summary
Вложения
Delays_TIMER1.rar
(9.95 КБ) 161 скачивание
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Спасибо, Илья! Правда, уже сам нашёл такие ATmega. У ATtiny (12,13,2313,4313,24...84 и т.д.) такой возможности нет.
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Сообщение ILYAUL »

akl писал(а): У ATtiny (12,13,2313,4313,24...84 и т.д.) такой возможности нет.
Да , это попутал .
Встал на лапы
Аватара пользователя
Сообщения: 126
Зарегистрирован: Пн ноя 05, 2012 22:23:32
Откуда: Санкт-Петербург

Сообщение VanyaSV »

мяу)
почему в atmega128 не срабатывает команда sbr flags,(1<<clk)?
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение 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
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Коллеги, как я понял, все метки, объявленные внутри макрокоманды - временные. А нет ли возможности сгенерить внутри макрокоманды постоянную метку? Чтобы она действовала не только внутри макрорасширения, но и в основном тексте?
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Тогда это будет подпрограмма.
Docendo discimus
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6348
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

afz писал(а): все метки, объявленные внутри макрокоманды - временные. А нет ли возможности сгенерить внутри макрокоманды постоянную метку? Чтобы она действовала не только внутри макрорасширения, но и в основном тексте?
Ну а сам как думаешь ? Вызвал N раз макрос, получил N макрорасширений с N метками. Все они глобальные, причем адреса разные, а имя одно. :( ( Кстати, нет временных и постоянных, есть локальные и глобальные . Временная - это как : после того, как к ней обратились - она стирается ? :) ) .
Поставил метку пред макровызовом - она и будет глобальной, делов-то.
А вообще попытка rjmp внутрь чего-то ( неважно - подпрограммы, макрорасширения ) - это порочный стиль "через опу". Языки высокого уровня это не допускают, и правильно делают, но на ассемблере можно и выпендриться. Как говорится, в сумасшедшем доме и не такое делают.
Ничего личного. Просто мое убеждение, основанное на рекомендациях корифеев и 40 годах практики.
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение 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'а сохраняется в стеке.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я уже многое забыл, но по-моему у AVR-овского ассемблера метки внутри макросов остаются глобальными, а чтобы они были локальными, нужен какой-то особый синтаксис - то ли @1, то ли что-то похожее... проверьте, а то я и сам не уверен в том, что говорю - смутные воспоминания...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение 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, вызывающий блок макрокоманд для соответствующего контроллера, и все. Сделал, не поленился, сочинил программулю для писюка, которая из листинга, скопированного из даташита, генерит этот набор макрокоманд, попробовал, и тут прилетела птица Обломинго - метки внутри макрорасширения строго локальные...
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение 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	
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение 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 *

 
Начиная новый проект копипастим все это целиком в пустой файл ассемблерного текста, остальное ясно из комментариев.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Ответить

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