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

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Сообщение ВитГо »

Gudd-Head писал(а):
ВитГо писал(а):Очень нуждаюсь в алгоритме рисовании линии на ассемблере.
Интересно, конечно, где вы её (линию) будете рисовать — на бумаге? :)
А так — формула линии из алгебры 5-го класса: y = k*x + b, т.е. реализовать на АСМе умножение и сложение, потом подставлять вместо х нужный диапазон точек.
Нее, на бумаге не рисую :-)

я уже писал про алгебру.... повторю еще раз - этот способ меня не устраивает...

сейчас практически додумал итерационный метод... но он работает не всегда.. возможно я чтото не додумал...

кто то еще решал подобную задачу ?

мой метод:
поскольку описывать долго, опишу на примере
предположим нужно построить линию из 0, 0 в координаты 8, 5
сначала заполняем матрицу смещений,
Для этого делим большее смещение конечной точки на меньшее последовательно до получения остатка от деления равного нулю
8 \ 5 = 1 остаток 3 - теперь используем остаток от деления =3 для нового деления
8 \ 3 = 2 остаток 2 - теперь используем остаток от деления =2 для нового деления
8 \ 2 = 4 остаток 0 - остаток 0, заполнение матрицы смещений закончено

соответственно нам нужно смещаться:
на 1 точку каждый шаг,
на 2 точки каждый второй шаг,
и на 3 точки каждый четвертый шаг...

Построим линию:
_12345 - по горизонтали (1..5) шкала шага, а по вертикали (1..8 ) - шкала смещений
1+
2_+
3_+
4__+
5___+
6___+
7___+
8____+

вот где то так...
но я находил некоторые примеры где этот код дает некрасивую линию :-(((

Может быть ктото сталкивался с другими алгоритмами ? (не алгебраическими)

p.s. а вы говорите формула по алгебре... !!! :-)

кстати, мой кот постоянно почему то ложиться на полу на что нить... то на коврик, то на пакет, то на бумагу.. - это у него прикол такой или они все так делают ? чем ему лежать непосредственно на полу (ламинат, кафельная плитка) не нравиться?!
Реклама
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город

Сообщение Мастер Ломастер »

ВитГо писал(а):Очень нуждаюсь в алгоритме рисовании линии на ассемблере..
погуглите "алгоритм брезенхема" - реализуется только при помощи целочисленного сложения и вычитания (т.е. умножения-деления не требуется), на ассемблере - без проблем, если сумеете АЛГОРИТМ на нем изложить. для рисования линий и предназначен.
битва с дураками проиграна, победители торжествуют. слава победителям!
Контактная информация:
Реклама
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Сообщение ВитГо »

Мастер Ломастер писал(а):
ВитГо писал(а):Очень нуждаюсь в алгоритме рисовании линии на ассемблере..
погуглите "алгоритм брезенхема" - реализуется только при помощи целочисленного сложения и вычитания (т.е. умножения-деления не требуется), на ассемблере - без проблем, если сумеете АЛГОРИТМ на нем изложить. для рисования линий и предназначен.
ОГРОМНОЕ ПРЕ-ОГРОМНОЕ !! то что нужно !!!
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Мастер Ломастер писал(а):погуглите "алгоритм брезенхема"
Вот это круть 8)
ВитГо писал(а):кстати, мой кот постоянно почему то ложиться на полу на что нить... то на коврик, то на пакет, то на бумагу.. - это у него прикол такой или они все так делают ? чем ему лежать непосредственно на полу (ламинат, кафельная плитка) не нравиться?!
Все они так делают... так теплее. Мой, правда, пакетик рвёт на мелкие части... а вот на бумаге очень любит лежать.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Сообщение ВитГо »

Ну если вдруг кому понадобиться...
Алгоритм рисования линии Брезенхейма

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

;=========================
;																					   Вывод линии
; temp : temp1	- X1, Y1 - координаты начала отрезка
; temp2: temp3	- X2, Y2 - координаты конца отрезка
LCD_LINE:
					PUSH	temp
					PUSH	temp1
					PUSH	temp2
					PUSH	temp3
					PUSH	temp4
					PUSH	temp5
					PUSH	temp6
					PUSH	temp7
					PUSH	ZL

					; расчет параметра DX
					MOV		temp4	, temp2
					SUB		temp4	, temp
					BRCC	LCD_LINE_NO_INV_DX
					NEG		temp4				
LCD_LINE_NO_INV_DX:	; temp4 = dx

					; расчет параметра DY
					MOV		temp5	, temp3
					SUB		temp5	, temp1	
					BRCC	LCD_LINE_NO_INV_DY
					NEG		temp5				
LCD_LINE_NO_INV_DY:	; temp5 = dy

					; расчет параметра S1
					MOV		temp6	, temp2
					SUB		temp6	, temp
					BRNE	LCD_LINE_S1_NOT_NULL
					LDI		temp6	, 0			; s1 =  0
					RJMP	LCD_LINE_S1_READY
LCD_LINE_S1_NOT_NULL:
					BRCC	LCD_LINE_S1_VAL_1
					LDI		temp6	, -1		; s1 = -1
					RJMP	LCD_LINE_S1_READY
LCD_LINE_S1_VAL_1:
					LDI		temp6	, 1			; s1 =  1
LCD_LINE_S1_READY:	; temp6 = s1

					; расчет параметра S2
					MOV		temp7	, temp3
					SUB		temp7	, temp1
					BRNE	LCD_LINE_S2_NOT_NULL
					LDI		temp7	, 0			; s2 =  0
					RJMP	LCD_LINE_S2_READY
LCD_LINE_S2_NOT_NULL:
					BRCC	LCD_LINE_S2_VAL_1
					LDI		temp7	, -1		; s2 = -1
					RJMP	LCD_LINE_S2_READY
LCD_LINE_S2_VAL_1:
					LDI		temp7	, 1			; s2 =  1
LCD_LINE_S2_READY:	; temp7 = s2
			
					; обмен значений dx и dy в зависимости от углового коэффициента наклона отрезка
					CP	temp5	, temp4			; dy>dx
					BRLO	LCD_LINE_CHANGE_0
					; обмен значений
					PUSH	temp5
					PUSH	temp4
					POP		temp5
					POP		temp4
					LDI		temp2	, 1			; Обмен=1
					RJMP	LCD_LINE_CHANGE_READY
LCD_LINE_CHANGE_0:	; нет обмена
					LDI		temp2	, 0			; Обмен=0
LCD_LINE_CHANGE_READY:	; обмен значений dx и dy осуществлен


					MOV		temp3	, temp5		; e = dy
					ADD		temp3	, temp5		; e = 2*dy
					SUB		temp3	, temp4		; e = 2*dy - dx

					MOV		ZL		, temp4		; ПЕРЕМЕННАЯ ЦИКЛА
LCD_LINE_LOOP:		; цикл

					CALL	LCD_PIX				; рисуем пиксел, temp-x, temp1-y

LCD_LINE_WHILE:
					CPI		temp3	, 128		; while (e>0)
					BRCC	LCD_LINE_WHILE_END	;

					CPI		temp2	, 1			; if Обмен = 1
					BRNE	LCD_LINE_CHANGE_NO
					; Обмен = 1
					ADD		temp	, temp6		; if Обмен=1 then x = x+s1
					RJMP	LCD_LINE_END_IF
LCD_LINE_CHANGE_NO:	; Обмен = 0
					ADD		temp1	, temp7		; if Обмен=0 then y = y+s1
LCD_LINE_END_IF:
					SUB		temp3	, temp4
					SUB		temp3	, temp4

					RJMP	LCD_LINE_WHILE		; выполняем цикл while
LCD_LINE_WHILE_END:	; end while

					CPI		temp2	, 1			; if Обмен = 1
					BRNE	LCD_LINE_CHANGE1_NO
					; Обмен = 1
					ADD		temp1	, temp7		; if Обмен=0 then y = y+s1
					RJMP	LCD_LINE_END_IF1
LCD_LINE_CHANGE1_NO:	; Обмен = 0
					ADD		temp	, temp6		; if Обмен=1 then x = x+s1
LCD_LINE_END_IF1:
					ADD		temp3	, temp5
					ADD		temp3	, temp5

					DEC		ZL
					CPI		ZL	, 0
					BRNE	LCD_LINE_LOOP

					POP		ZL
					POP		temp7
					POP		temp6
					POP		temp5
					POP		temp4
					POP		temp3
					POP		temp2
					POP		temp1
					POP		temp
					RET
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

ВитГо писал(а):Ну если вдруг кому понадобится...
Алгоритм рисования линии Брезенхейма
Блин, нифига себе... и это чтобы нарисовать одну единственную линию??? :shock:
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Gudd-Head писал(а):
ВитГо писал(а):Ну если вдруг кому понадобится...
Алгоритм рисования линии Брезенхейма
Блин, нифига себе... и это чтобы нарисовать одну единственную линию??? :shock:
лишний повод задуматься о Си :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Сообщение ВитГо »

эта процедура "весит" 155 байт...
о каком СИ вы говорите ?!
там одна библиотека умножения деления дробных чисел будет весить за килобайт...!!!


гм.. если я скажу что уже написал кода на 8 кб и еще около 6 кб строки и настройки - то я по вашему буду вообще извращенцем чтоли ? :-)))

Если честно я не вижу сейчас ничего сложного чтобы переходить на Си.. даже наоборот... после написания десятка-полутора вспомогательных процедур код такой же простой как написанный на Си... но намного меньше...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ВитГо писал(а):эта процедура "весит" 155 байт...
о каком СИ вы говорите ?!
там одна библиотека умножения деления дробных чисел будет весить за килобайт...!!!
не будет: для брезенхема дробные числа не нужны. и брезенхем у меня отлично влезал в тини13 вместе со всякими вспомогательными штуками - на чистом Си :))) а вот вы на ассемблере попробуйте умножать-делить числа с плавающей точкой :)))
ВитГо писал(а):гм.. если я скажу что уже написал кода на 8 кб и еще около 6 кб строки и настройки - то я по вашему буду вообще извращенцем чтоли ? :-)))
в свое время я и поболее писал :) все ништяк
ВитГо писал(а):Если честно я не вижу сейчас ничего сложного чтобы переходить на Си..
дык вроде и не в ваш адрес было мое замечение :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Родился
Сообщения: 8
Зарегистрирован: Пт июл 09, 2010 10:55:13

Сообщение sergy1976 »

Здравствуйте, хелп ми
Начал изучать асм. Простейшая программа переключения светодиодов. ATMega16 на макетке, пишу в AvrStudio 4.18. Восемь светодиодов подключены к порту В, катодом на землю. Зажигать отдельные светодиоды получается. Решил попробывать с задержкой, причем с самой простейшей с условным переходом по флагу Z.
При выполнении программы по первому примеру остаются включенными 4 старших светодиода. Т.е. МК выполнил программу и остановился. Вечного цикла нет.

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

	.include "m16def.inc"   ; Используем ATMega16

		.def temp=R16 ; регистр для настроек
		.def rab=R17  ; регистр для вывода в порт

; RAM =================
		.DSEG			; Сегмент ОЗУ
 
 ; FLASH ===============
		.CSEG			; Кодовый сегмент
		.org 0
	
		ldi temp, low(RAMEND) ; инициализация стека
		out SPL, temp
		ldi temp, high(RAMEND)
		out SPH, temp

		ldi temp, 0xFF	; порт В на выход
		out DDRB, temp
		ldi rab, 0b00001111 
		out PortB, rab ;зажигаем 4 младших светика

		ldi rab, 0b11110000
		out PortB, rab ;зажигаем 4 старших светика
Далее вставляю в код задержку на переключение на старшие разряды, компилирую, прошиваю МК. Выполняется, сначала горят младшие, НО после задержки на мгновение вспыхивают светодиоды на старших светодиодах (на мгновение потому что нет еще одной задержки). Т.е. получается, что при использовании переходов программа компилируется таким образом, что она болтается в цикле? Я же не указал явно переход на начало программы. Мне казалось что, сначала должны гореть младшие светодиоды, через некоторые время старшие (и далее постоянно они). Без переключений. Разъясните плиз, где не догоняю-)))

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


		.include "m16def.inc"   ; Используем ATMega16

		.def temp=R16 ; регистр для настроек
		.def rab=R17  ; регистр для вывода в порт
		.def razr0=R18 ;регистры для организации задержки
		.def razr1=R19
		.def razr2=R20
  
; RAM =================
		.DSEG			; Сегмент ОЗУ
 
 ; FLASH ===============
		.CSEG			; Кодовый сегмент
		.org 0
	
		ldi temp, low(RAMEND) ; инициализация стека
		out SPL, temp
		ldi temp, high(RAMEND)
		out SPH, temp

		ldi temp, 0xFF	; порт В на выход
		out DDRB, temp
loop1:
		ldi rab, 0b00001111 
		out PortB, rab ;зажигаем 4 младших светика

		ldi razr0, 0x03 ;устанавливаем время задержки
		ldi razr1, 0x0B
		ldi razr2, 0x47

delay1:	dec razr0
		brne delay1
		dec razr1
		brne delay1
		dec razr2
		brne delay1
		
		ldi rab, 0b11110000
		out PortB, rab ;зажигаем 4 старших светика

;       ДОЛЖНА ЛИ ЗДЕСЬ ПРОГРАММА ОСТАНОВИТЬСЯ?


;		ldi razr0, 0x03 ;устанавливаем время задержки
;		ldi razr1, 0x0B
;		ldi razr2, 0x47

;delay2:
;	
;		dec razr0
;		brne delay2
;		dec razr1
;		brne delay2
;		dec razr2
;		brne delay2

;loop1: rjmp loop1
 
; EEPROM ==============
		.ESEG			; Сегмент EEPROM
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

sergy1976 писал(а):При выполнении программы по первому примеру остаются включенными 4 старших светодиода. Т.е. МК выполнил программу и остановился. Вечного цикла нет.
А вот и не остановился. 4 младших светодиода вспыхивают на 2 такта, но вы этого не замечаете, программа выполняется в месте с тем кодом, что после вашего (если МК был стёрт, то там NOPы).
sergy1976 писал(а):Выполняется, сначала горят младшие, НО после задержки на мгновение вспыхивают светодиоды на старших разрядах
Время вспыха как раз и есть время выполнения ~ 8 тысяч NOPов, при тактовой 1 МГц — 8 мс.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Родился
Сообщения: 8
Зарегистрирован: Пт июл 09, 2010 10:55:13

Сообщение sergy1976 »

значит не остановился? т.е. пробежал по NOPам и снова ушел на начало программы? Ведь зацикливания нет. Это основной вопрос сейчас у меня.
Про два такта понял, это выполнение команд LDI и OUT
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

sergy1976 писал(а):значит не остановился? т.е. пробежал по NOPам и снова ушел на начало программы? Ведь зацикливания нет. Это основной вопрос сейчас у меня.
Да, пробежал и пошёл заново. МК застопорится если написать rjmp PC (что аналогично строке Label: rjmp Label), где РС — счётчик команд (program counter).
sergy1976 писал(а):Про два такта понял, это выполнение команд LDI и OUT
Да.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Родился
Сообщения: 8
Зарегистрирован: Пт июл 09, 2010 10:55:13

Сообщение sergy1976 »

догнал, спасибо-)
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

добрый день, знатоки :))
я новичок, и по немногу учу ассемблер в надежде что когда-либо и я смогу черконуть примитивную прогу для атмеги.......
на данный момент мне непонятен смысл следующих команд:
.CSEG
и
.ORG address
может кто из вас в силах обяснить по доходчивей....?
Tell Me The Truth
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

.CSEG говорит компилятору, что далее идёт сегмент кода (что всё, что ниже, ему во флешь записать надо), а .ORG address - с какого адреса (например .ORG 0 - значит "пиши сначала")
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

.CSEG говорит компилятору, что все нижеследующие данные должны быть расположены во FLASH, т.е. открывается секция, собственно, самого кода.
.DSEG указывает, что нижеследующие данные должны быть расположены в ОЗУ. Писать туда какие либо константы, естественно, нельзя. Это можно только во время выполнения. Но тут можно зарезервировать места для переменных или каких либо данных.
.EESEG указывает, что нижеследующие данные должны быть располагаться в EEPROM.
.ORG устанавливает адрес, откуда будут писаться нижеследующие данные или код. Применимо во всех секциях. Следует учитывать, что в FLASH адресация идут по словам (по 2 байта). В ОЗУ и EEPROM, как обычно, по байтам.


Ну вот, опередили. :)
Короче, читай документацию по макроассемблеру AVR.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

понял, пока буду переваривать
а может кто из знатоков знает толково-просто-понимающийся интернет ресурс по данной тематике или книжку.....?
буду весьма признателен.... :))
Tell Me The Truth
Друг Кота
Аватара пользователя
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....

Сообщение Meteor »

Более-менее можно такую книжку качнуть (как раз про оржи, ксеги..)
Плюс конечно "Применение микроконтроллеров AVR"
На мой взгляд большего не надо
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 383
Зарегистрирован: Пн мар 16, 2009 23:35:42
Откуда: Украина Новоднестровск

Сообщение nibiluk »

FreshMan писал(а):понял, пока буду переваривать
а может кто из знатоков знает толково-просто-понимающийся интернет ресурс по данной тематике или книжку.....?
буду весьма признателен.... :))
Вот тут вроде нормально http://easyelectronics.ru/category/avr-uchebnyj-kurs
Всем известно что любая микросхема работает на дыме, и если волшебный дым из неё вышел то она перестает работать.
Ответить

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