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

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

Добавлено: Ср мар 26, 2014 19:54:06
xkp
dr.doc писал(а):convert BIN to BCD.
что то не понятный ваш конвертер. и где метка bBCDx_2, на которую посылает brne?

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

Добавлено: Ср мар 26, 2014 20:03:27
alexsaska
Спасибо всем! Буду разбираться :) :shock:

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

Добавлено: Ср мар 26, 2014 21:48:13
WiseLord
xkp писал(а):Берем наше число Х и делим его на 10000, результат в IND4. Остаток от Х теперь делим на 1000 - результат в IND3, остаток делим на 100 - IND2, остаток делим на 10 - IND1, и оставшийся остаток это IND0.
Не кажется ли Вам, что слишком много делений (в том числе, возможно, и для нахождения остатка)?
AVR и так не имеет аппаратного деления, а тут ещё и двухбайтовые величины. Может быть очень медленно. Не зря ведь тут народ обсуждает разные хитрости.

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

Добавлено: Ср мар 26, 2014 21:59:58
xkp
А как иначе разложить число на разряды? Деление тут сказано образно, для смысла. А если подробнее то из Х вычитаем 10000 и если флаг переноса сброшен то IND4+1, если флаг переноса установлен то Х+10000. Далее Х-1000 .... процедура такая же для 1000,100,10

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

Добавлено: Ср мар 26, 2014 22:02:46
ploop
Без делений никак. Аппаратного нет, само собой, но простой алгоритм (рабочий) я уже дал. Что рабочий не сомневайтесь, вон, передо мной стоит, циферки кажет на 14ти семисегментниках :)

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

Добавлено: Ср мар 26, 2014 22:09:49
Alexeyslav
Что значит никак? Большинство извстных мне алгоритмов основаны на вычитаниях... где же там деление?
Вот как-то так (выдрано и адаптировано с какой-то большой библиотеки функций)

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

#define		BCD16res0 R2
#define		BCD16res1 R3
#define		BCD16res2 R4
#define		bin16r0 ACCUM      - регистры входных данных(только регистры R16-R31)
#define		bin16r1 ACCUMH
#define		BB16_cnt1 tempi    - временные регистры(только регистры R16-R31) после исполнения портятся
#define		BB16_cnt2 tempih


// Input : ACCUMH:ACCUM - binary, X - pointer to 3 byte RAM for result
// Output: (X):(X+1):(X+2) - result of BCD conversion.

bin2BCD:
 push	BCD16res0
 push	BCD16res1
 push	BCD16res2

 ser	BB16_cnt2
 mov	BCD16res2,	BB16_cnt2

BB16p5_L10k:   
 inc	BCD16res2
 subi	bin16r0,	low(10000)
 sbci	bin16r1,	high(10000)
 brcc	BB16p5_L10k
 subi	bin16r0,	low(-10000)
 sbci	bin16r1,	high(-10000)
 ldi	BB16_cnt1,	(256-16)

BB16p5_L1k:
 subi	BB16_cnt1,	(-16)
 subi	bin16r0,	low(1000)
 sbci	bin16r1,	high(1000)
 brcc	BB16p5_L1k
 subi	bin16r0,	low(-1000)
 sbci	bin16r1,	high(-1000)
 mov	BCD16res1,	BB16_cnt2

BB16p5_L100:
 inc	BCD16res1
 subi	bin16r0,	low(100)
 sbci	bin16r1,	high(100)
 brcc	BB16p5_L100
 subi	bin16r0,	low(-100)
 or		BCD16res1,	BB16_cnt1
 ldi	BB16_cnt1,	(256-16)

BB16p5_L10:
 subi	BB16_cnt1,	-16
 subi	bin16r0,	 10
 brcc	BB16p5_L10
 subi	bin16r0,	-10
 mov	BCD16res0,	BB16_cnt1
 or		BCD16res0,	bin16r0

// выгрузка в RAM
 ST	X+, BCD16res0
 ST	X+, BCD16res1
 ST	X+, BCD16res2

 pop	BCD16res2
 pop	BCD16res1
 pop	BCD16res0

 ret 

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

Добавлено: Ср мар 26, 2014 22:28:22
ploop
Alexeyslav писал(а):Что значит никак? Большинство извстных мне алгоритмов основаны на вычитаниях... где же там деление?
Большинство? :)))
Я бы посмотрел на алгоритм произвольного деления без использования вычитаний... :wink:

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

Добавлено: Ср мар 26, 2014 22:44:05
xkp
так ваше циклическое вычитание одного и того же числа это и есть деление...
Алгоритм деление 2-хбайтного числа на однобайтное
Спойлер;============
;= Деление R25,R24 на R20 =
;= R25,R24 - результат, R21 - остаток =
;= используются TMP, R20, R21, R24, R25 =
;============

div_2_1:
ldi tmp,$10
clr r21
div_2_10:
lsl r24
rol r25
rol r21
brcs div_2_11
cp r21,r20
brlo div_2_12
div_2_11:
sub r21,r20
inc r24
div_2_12:
dec tmp
brne div_2_10
ret
если кому надо есть и другие заготовки делений и умножений, начиная от 2 на 1, заканчивая 4 на 3, цифры подразумевают количество байт.

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

Добавлено: Ср мар 26, 2014 22:52:51
dr.doc
Прошу прощения, недоглядел. Выкладываю полный вариант.

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

Добавлено: Вс мар 30, 2014 17:59:05
alexsaska
Разобрался и с этим)))) Всем спасибо за помощь! Ну и написал свой алгоритм разложения однобайтного числа для семи сегментного индикатора:
Спойлер

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

			ldi r16, 0x37 // заносим число 55, делимое
				/// значения деления кладем в r18, r19
				///деление
delenie:	        clr r18
			clr r19 //очищаем r18,r19
minus_10:	        cpi r16,0xA //сравниваем r16 и 10
			brlo minus_1 // выходим
			subi r16,0xA // вычитаем из r16 10
			inc r18 // инкремент r18 
			rjmp minus_10
minus_1:	        cpi r16,0x1
			brlo exit
			subi r16,0x1
			inc r19
			rjmp minus_1
exit:		        ret

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

Добавлено: Вс мар 30, 2014 18:04:57
Alexeyslav
И оно работает только до 99... а единицы можно просто скопировать с исходного числа после вычитания десятков... зачем лишний раз цикл крутить.

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

Добавлено: Вс мар 30, 2014 18:09:11
alexsaska
Alexeyslav писал(а): а единицы можно просто скопировать с исходного числа после вычитания десятков... зачем лишний раз цикл крутить.
насчет единиц не подумал..

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

Добавлено: Вт апр 08, 2014 17:46:10
Muzykant
Здравствуйте!
Помогите разобраться с таким вопросом: нигде толком ничего не написано про массивы на простых примерах.
Например на тех же самых светодиодах. Допустим программа на Си выглядела бы как:

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

 unsigned char step=0;           
 unsigned char Data[4] = {0b00001000,0b00000100,0b00000010,0b00000001};
 void main(void)
{
 while (1)
          {
          PORTC=Data[step]; 
          step++;         
          if (step == 4)                                
          step=0;   
          }
}
 
Т.е. мы просто по очереди мигаем 4-мя светодиодами. А как это написать с использованием массива не пойму.
И далее на усложнение - подключить кнопку и при нажатии делать step-- с того места, на котором нажали кнопку.

С объявлением массивов-то вроде понятно
.db 1,2,3,4,5
А вот как происходит обращение к конкретному элементу - неясно

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

Добавлено: Вт апр 08, 2014 20:27:33
Alexeyslav
Для этого есть команды LPM и SPM работают они с индексным регистром, в него надо загрузить адрес... и обязательно учесть тот факт что метка адресует память СЛОВАМИ, а доступ к памяти через LPM - байтами, т.е. адрес метки надо умножать на два и получится номер байта с которого начинается массив, а дальше прибавляешь необходимое смещение и вперед.

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

Добавлено: Ср апр 09, 2014 00:33:51
Muzykant
Т.е. сначала в любом случае обращаемся к 0-му элементу, а потом от него уже считаем нужный нам.

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

          ldi Temp,0            

ReadArray:
          ldi ZH,High(MyArray*2) ;загрузка адреса 0-го
          ldi ZL,Low(MyArray*2)  ;элемента в рег. пару Z

          ldi Temp1,0
          add ZL,Temp          ;прибавление
          adc ZH,Temp1         ;внутр. адреса
Спасибо! Странно, Вы вроде и нового ничего не сказали, но теперь я, кажется, начал понимать..)

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

Добавлено: Ср апр 09, 2014 09:49:19
Gudd-Head
Muzykant писал(а):Вы вроде и нового ничего не сказали, но теперь я, кажется, начал понимать..
Массивы (до 256 элементов) удобно располагать в памяти программ начиная с нулевого младшего адресного байта, например, $F00 или $1300.
Тогда старший адресный байт можно не трогать :)

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

Добавлено: Ср апр 09, 2014 09:51:27
Muzykant
Вот тут не совсем понял.. А можно пример?

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

Добавлено: Ср апр 09, 2014 10:03:17
Gudd-Head

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

ldi ZH,High(MyArray*2) ;загрузка адреса 0-го элемента в рег. пару Z
clr ZL  ; младший адресный байт нулевой, 
; равнозначно ldi ZH,High(MyArray*2)

ldi Temp1,0
add ZL,Temp ;прибавление внутр. адреса
; ZH уже трогать не надо, он у всех элементов массива одинаковый
...

.CSEG
.ORG $F00 ; явно указываем где разместить массив
MyArray:
.DB $01, $03, ... ; массив до 256 байт
Мелочь, а приятно. Позволяет сократить код и ускорить быстродействие.

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

Добавлено: Ср апр 09, 2014 11:08:15
Muzykant
Спасибо за эту информацию, попробую сегодня обязательно. Меня как раз интересовало, зачем использовать 2 байта, если в массиве всего несколько элементов.

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

Добавлено: Ср апр 09, 2014 11:16:04
Gudd-Head
Muzykant писал(а):Меня как раз интересовало, зачем использовать 2 байта, если в массиве всего несколько элементов.
Это потому что память программ у МК больше 256 команд (512 байт), потому и адресация двухбайтная.