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

Обсуждаем контроллеры компании Atmel.
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Как вариант

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

	LSR	R17
	ROR	R16
	LSR	R17
	ROR	R16

	LSL	R16
	ROL	R17
	LSL	R16
	ROL	R17
Реклама
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

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

Сообщение Pink-Pank »

Вроде как lsl, lsr не работают с флагом Carry. У Вас потеряются биты.
Fucking static initialization order fiasco
Реклама
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

Это кто вам сказал? lsr сдвигает вправо, на место 7-го бита ставится 0, 0-й бит помещается в C. lsl - наоборот, на место 0-го ставится 0, 7-й уходит в С.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

COKPOWEHEU, вот именно. И бит от первого сдвига потеряется : В С - то он задвинулся, но во втором LSL/LSR не используется, заполняется нулем. Но и вариант zero648 не самый оптимальный.

Лучше всего так, как у aki

Земляк WiseLord меня опередил. Минчане, чего вам не рождествуется, все форумуетесь :)
Последний раз редактировалось Jack_A Ср янв 07, 2015 11:47:13, всего редактировалось 6 раз.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Получается как-то так:

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

        |   R17    |   R16    | C
--------+----------+--------------
        | abcdefgh | ijklmnop | x
--------+----------+----------+---
LSR R17 | 0abcdefg | ijklmnop | h
ROR R16 | 0abcdefg | hijklmno | p
LSR R17 | 00abcdef | hijklmno | g
ROR R16 | 00abcdef | ghijklmn | o

        |   R17    |   R16    | C
--------+----------+--------------
        | abcdefgh | ijklmnop | x
--------+----------+----------+---
LSL R16 | abcdefgh | jklmnop0 | i
ROL R17 | bcdefghi | jklmnop0 | p
LSL R16 | bcdefghi | klmnop00 | j
ROL R17 | cdefghij | klnmop00 | o
Реклама
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

Вопрос:

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

			.equ	DB4		= PORTC7
			.equ	DB5		= PORTВ6
			.equ	DB6		= PORTА0
			.equ	DB7		= PORTD3
Так будет работать? Т.е. я хочу подключить к разным пинам разных портов. Будет ли у меня далее в программе понимать, что DB4 - это PORTC7?
Станислав
Реклама
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Не будет. Директива .equ просто определяет числовой константе символьное имя для более легкого понимания и модификации исходника программы. Ну какое число можно сопоставить в директиве .equ DB4 = PORTC7 идентификатору 'PORTC7' так, чтобы одним числом выражался и адрес порта, и номер бита в нем ? И вообще, директива ассемблера -- не волшебная палочка, которая может делать то, что не может делать машинный код. Ну представьте, что вышеуказанную директиву компилятор принял, и у вас написано выражение, где это DB4 использовано. Какой машинный код будет сгенерирован в этом случае ?
Последний раз редактировалось Jack_A Ср янв 07, 2015 12:16:25, всего редактировалось 1 раз.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

Блин.... И я об этом думаю. Поэтому и задал вопрос для того, чтобы подтвердить сомнения...
Тогда другой вопрос.
Хочу назначить выводы индикатора на любые пины ЛЮБЫХ портов МК. Как правильно их объявить (определить)? Хочу дальше в программе не заморачиваться и писать ДБ4, а подобие дефайнов само определяло, куда он там подключен.
Станислав
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Я думаю, с помощью макросов. Изменяя параметры в вызове макроса или макроопределении, можно изменять назначение разрядов/адресов. А "само" типа "разбирайтесь по своим местам" ничего не сможет, по любому назначения определяются в программе, и для того, чтобы прогу лучше понимать/корректировать макросы -- хороший инструмент.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

А ведь, точно! Мне же по сути не нужны по отдельности линии DB, мне нужен целиком порт и значение в нем.
Спойлер

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

			
			.equ	DB7port = PORTC
			.equ	DB7pin	= 3

			.equ	DB6port = PORTC
			.equ	DB6pin  = 2

			.equ	DB5port = PORTC
			.equ	DB5pin  = 1

			.equ	DB4port = PORTC
			.equ	DB4pin  = 0

			.equ	RSport  = PORTC
			.equ	RSpin   = 5

			.equ	Eport	= PORTC
			.equ	Epin	= 4
		
	
	.MACRO	DATA						; Вызываем просто DATA TETRADA, предварительно положив в ТЕТРАДУ то, что нужно вывести.

				lsr @0				; Сдвигаем вправо, крайний вывалится в С
				brcc Pusto1				; Если С=0, то переходим по метке
				sbi  DB4port, DB4pin	; Иначе, выставляем бит в 1
				rjmp Next1				; Идем проверять следующий
		Pusto1: cbi	 DB4port, DB4pin	; Выставляем бит в 0
			

		Next1:	lsr @0				; Сдвигаем вправо, крайний вывалится в С
				brcc Pusto2				; Если С=0, то переходим по метке
				sbi  DB5port, DB5pin	; Иначе, выставляем бит в 1
				rjmp Next2				; Идем проверять следующий
		Pusto2: cbi	 DB5port, DB5pin	; Выставляем бит в 0
			

		Next2:	lsr @0				; Сдвигаем вправо, крайний вывалится в С
				brcc Pusto3				; Если С=0, то переходим по метке
				sbi  DB6port, DB6pin	; Иначе, выставляем бит в 1
				rjmp Next3				; Идем проверять следующий
		Pusto3: cbi	 DB6port, DB6pin	; Выставляем бит в 0
			

		Next3:	lsr @0				; Сдвигаем вправо, крайний вывалится в С
				brcc Pusto4				; Если С=0, то переходим по метке
				sbi  DB7port, DB7pin	; Иначе, выставляем бит в 1
				rjmp Next1				; Идем проверять следующий
		Pusto4: cbi	 DB7port, DB7pin	; Выставляем бит в 0
			
	
	.ENDM
А так будет работать? Думаю, что будет. Но код не оптимальный... Может кто ткнет носом, как проще вывести то, что находится в флаге переноса прямо на пин нужного порта?
Последний раз редактировалось СКАЗОЧНИК Ср янв 07, 2015 14:15:37, всего редактировалось 1 раз.
Станислав
Аватара пользователя
Леонид Иванович
Друг Кота
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск
Контактная информация:

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

Сообщение Леонид Иванович »

Вывод на индикатор с произвольным расположением портов делал так:
Спойлер

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

;Write nibble to LCD:
;Input:	temp7..temp4 - data nibble

LCD_WN:	bbrc	temp,7,lwr7_0
	Port_LCD_D7_1		;D7 <- 1
	rjmp	lwr6	
lwr7_0:	Port_LCD_D7_0		;D7 <- 0
lwr6:	bbrc	temp,6,lwr6_0
	Port_LCD_D6_1		;D6 <- 1
	rjmp	lwr5	
lwr6_0:	Port_LCD_D6_0		;D6 <- 0
lwr5:	bbrc	temp,5,lwr5_0
	Port_LCD_D5_1		;D5 <- 1
	rjmp	lwr4	
lwr5_0:	Port_LCD_D5_0		;D5 <- 0
lwr4:	bbrc	temp,4,lwr4_0
	Port_LCD_D4_1		;D4 <- 1
	rjmp	lwrend	
lwr4_0:	Port_LCD_D4_0		;D4 <- 0

lwrend:	Port_LCD_E_1		;E <- 1
	rcall	Delay		;delay 2 uS
	Port_LCD_E_0		;E <- 0
	ret
 
Там используется макрос, вот мои макросы:
Спойлер
;***** Macros

.macro clbr ;clear bit in register
cbr @0,exp2(@1)
.endm

.macro stbr ;set bit in register
sbr @0,exp2(@1)
.endm

.macro bbrc ;branch if bit in register clear
sbrs @0,@1
rjmp @2
.endm

.macro bbrs ;branch if bit in register set
sbrc @0,@1
rjmp @2
.endm

.macro bbic ;branch if bit in I/O clear
sbis @0,@1
rjmp @2
.endm

.macro bbis ;branch if bit in I/O set
sbic @0,@1
rjmp @2
.endm

.macro addi ;add immediate
subi @0,-@1
.endm

.macro ldx ;load XL, XH with word
ldi XL,byte1(@0)
ldi XH,byte2(@0)
.endm

.macro ldy ;load YL, YH with word
ldi YL,byte1(@0)
ldi YH,byte2(@0)
.endm

.macro ldz ;load ZL, ZH with word
ldi ZL,byte1(@0)
ldi ZH,byte2(@0)
.endm

.macro table ;load Z pointer
ldi ZL,low (@0*2)
ldi ZH,high(@0*2)
.endm

.macro stdi ;store immediate indirect with displacement
ldi temp,@1
std @0,temp
.endm

.macro ldsx ;load XL, XH from memory
lds XL,@0+0
lds XH,@0+1
.endm

.macro ldsy ;load YL, YH from memory
lds YL,@0+0
lds YH,@0+1
.endm

.macro ldsz ;load ZL, ZH from memory
lds ZL,@0+0
lds ZH,@0+1
.endm

.macro stsx ;store XL, XH in memory
sts @0+0,XL
sts @0+1,XH
.endm

.macro stsy ;store YL, YH in memory
sts @0+0,YL
sts @0+1,YH
.endm

.macro stsz ;store ZL, ZH in memory
sts @0+0,ZL
sts @0+1,ZH
.endm
Описание пинов портов делал так:
Спойлер

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

;
Port С:

.equ	DIRC	= 0b11111111		;Port C direction
.equ	PUPC	= 0b11111111		;Port C pull-ups

.equ	LCD_D6	= PC1			;LCD D6 data line
.equ	LCD_D7	= PC3			;LCD D7 data line

.macro	Port_LCD_D6_0			;LCD_D6 = 0
	cbi	PORTC,LCD_D6
.endm

.macro	Port_LCD_D6_1			;LCD_D6 = 1
	sbi	PORTC,LCD_D6
.endm

.macro	Port_LCD_D7_0			;LCD_D7 = 0
	cbi	PORTC,LCD_D7
.endm

.macro	Port_LCD_D7_1			;LCD_D7 = 1
	sbi	PORTC,LCD_D7
.endm

Port D:

.equ	DIRD	= 0b11111110		;Port D direction
.equ	PUPD	= 0b11111111		;Port D pull-ups
.equ	LCD_W	= PD2			;LCD W line
.equ	LCD_E	= PD3			;LCD E line
.equ	LCD_D4	= PD4			;LCD D4 data line
.equ	LCD_D5	= PD5			;LCD D5 data line

.macro	Port_LCD_W_0			;LCD_W = 0
	cbi	PORTD,LCD_W
.endm

.macro	Port_LCD_W_1			;LCD_W = 1
	sbi	PORTD,LCD_W
.endm

.macro	Port_LCD_E_0			;LCD_E = 0
	cbi	PORTD,LCD_E
.endm

.macro	Port_LCD_E_1			;LCD_E = 1
	sbi	PORTD,LCD_E
.endm

.macro	Port_LCD_D4_0			;LCD_D4 = 0
	cbi	PORTD,LCD_D4
.endm

.macro	Port_LCD_D4_1			;LCD_D4 = 1
	sbi	PORTD,LCD_D4
.endm

.macro	Port_LCD_D5_0			;LCD_D5 = 0
	cbi	PORTD,LCD_D5
.endm

.macro	Port_LCD_D5_1			;LCD_D5 = 1
	sbi	PORTD,LCD_D5
.endm
На ассемблере, правда, не пишу уже 10 лет.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

:facepalm: Леонид Иванович, я после каждого вашего поста себя таким тупым чувствую... :oops:
Спасибо, конечно за помощь, даже пробую разобраться. ))) Однако надо вопрос с повестки дня снять. Все равно по своему напишу все...
Станислав
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Вот от холода и нечего делать :) накропал универсальный макрос. Запуливает содержимое
бита С в нужный разряд нужного порта.

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

	.MACRO	C_in_PORT
	brcs	_10
	clt
	rjmp	_15
_10:	set
  ;  Перекинули  бит  С  в  бит  Т,  специально для этих  целей придуманный
_15:	in	temp,@0
	andi	r16,~(1<<@1)
  ;  Считали  порт  и  очистили  нужный  разряд
	bld	r16,@1
	out	@0,temp
  ;  заполнили  разряд  тем  чем  надо  и  закинули  обратно  в  порт.
	.ENDMACRO
Пример вызова : C_in_PORT PORTB,3 temp из диапазона R16...R31 определяется ранее директивой .def
Мож пригодится.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

Я забубенил так:
Спойлер

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

DB_LINE:							

					lsr  R17			    	        ; Сдвигаем вправо, крайний вывалится в С
					brcc Pusto1				; Если С=0, то переходим по метке
					sbi  DB4port, DB4pin         	; Иначе, выставляем бит в 1
					rjmp Next1				; Идем проверять следующий
			Pusto1:    cbi	 DB4port, DB4pin	        ; Выставляем бит в 0
			

			Next1:	lsr  R17				; Сдвигаем вправо, крайний вывалится в С
					brcc Pusto2				; Если С=0, то переходим по метке
					sbi  DB5port, DB5pin	; Иначе, выставляем бит в 1
					rjmp Next2				; Идем проверять следующий
			Pusto2: cbi	 DB5port, DB5pin	; Выставляем бит в 0
			

			Next2:	lsr  R17				; Сдвигаем вправо, крайний вывалится в С
					brcc Pusto3				; Если С=0, то переходим по метке
					sbi  DB6port, DB6pin	; Иначе, выставляем бит в 1
					rjmp Next3				; Идем проверять следующий
			Pusto3: cbi	 DB6port, DB6pin	; Выставляем бит в 0
			

			Next3:	lsr  R17				; Сдвигаем вправо, крайний вывалится в С
					brcc Pusto4				; Если С=0, то переходим по метке
					sbi  DB7port, DB7pin	; Иначе, выставляем бит в 1
					ret						; 
			Pusto4: cbi	 DB7port, DB7pin	; Выставляем бит в 0
			
	ret
Блин, выше же выкладывал уже... :facepalm:
Станислав
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

С использованием бита Т не надо никого никуда двигать.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

А как же если не двигать будут биты в С вываливаться?, чтобы потом их оттуда брать, потом в Т перекидывать, а дальше уже в порт. Тогды надо по другому задачу сформулировать. :roll:
Как раскидать младшую тетраду байта по различным пинам различных портов. :)
Станислав
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Ну тогда конечно... Изначально я понял задачу рулить битами по состоянию бита С. А вообще если биты в портах вразнобой, элегантного решения не получится. Абы работало :)
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

Коты... :cry: Может кому не лень будет, глянет в АВРстудии проект мой. Никак не могу понять, почему у меня руки из жопы... :dont_know:
Проект без ошибок в плане компиляции. Однако, после выхода из подпрограммы инициализации дисплея (по ret) попадает не туда, откуда начал...
Уже исправил одну проблему, когда перекидывало по ret выше на два адреса, а теперь НИЖЕ перекидывает...

З.Ы. За одно можете посмотреть мою реализацию выставления портов данных для индикатора. получилось вроде ОЧЕНЬ даже маленькая. ))))

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

DB_LINE:							; Выводим тетраду в линии дисплея
				rcall CLR_PORT
				
				sbrc 	R18, 4 			; Пропустить слудующую, еслли бит сброшен
				sbi		DB4port, DB4pin	; Ставим бит
				sbrc 	R18, 5 			; Пропустить слудующую, еслли бит сброшен
				sbi		DB5port, DB5pin	; Ставим бит
				sbrc 	R18, 6 			; Пропустить слудующую, еслли бит сброшен
				sbi		DB6port, DB6pin	; Ставим бит
				sbrc 	R18, 7 			; Пропустить слудующую, еслли бит сброшен
				sbi		DB7port, DB7pin	; Ставим бит			
	ret
Вложения
LCD2313.rar
(9.5 КБ) 139 скачиваний
Станислав
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

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

Сообщение Pink-Pank »

СКАЗОЧНИК писал(а):Коты... :cry: Может кому не лень будет, глянет в АВРстудии проект мой. Никак не могу понять, почему у меня руки из жопы... :dont_know:
Дык это не к нам. Это к проктологу. ;-)
А вообще, проверяйте стек. Где-то с push/pop не доглядели
Fucking static initialization order fiasco
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

В том то и дело, что стек инициализирован. Но он используется только самими подпрограммами по (rcall и ret). Я сам ничего в стек не кладу.... :dont_know: Все туда кладет и берет компилятор.
При отладке смотрел. Переполнений не происходит никаких, т.к. их и не может быть... Всего на три или четыре глубины прогружается в стек.

ЗЫ. Я думаю, у меня проблема со структурой самой программы и подключением ИНКЛУДАМИ... Где-то я последовательность нарушаю... Все должно быть элементарно, а я не вижу.
Станислав
Ответить

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