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

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

Добавлено: Вс май 27, 2012 21:17:21
мелкая
Alkul писал(а):
мелкая писал(а):Может кто нибудь объяснит как изменить код что бы получить интервал 1)0-6 2)0-9
под "интервалом" тут понимается количество итераций?
Диапазон!

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

Добавлено: Вс май 27, 2012 21:45:06
Alexeyslav
Ты не оттуда берешь случайное число, видимо. Там у тебя в непосредственной близости к выходу есть "ANDI R31,0xE0" что как бы уменьшает шансы на нормальное выделение диапазона, удивительно что оно тебе дает хоть что-то на выходе.
Бери там где у тебя на выходе имеется нормальное случайное число 0..255 хотябы.

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

Добавлено: Вс май 27, 2012 21:56:45
мелкая
Я очень сильно извиняюсь за свою бестолковость и надоедливость, но где найти это нормальное число на выходе???

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

Добавлено: Вс май 27, 2012 22:09:04
Alexeyslav
Алгоритм сама разрабатывала? По какому принципу он работает?
Классика - это длинный сдвиговый регистр с обратными связями.

В ЭТОТ алгоритм я еще не вкурил, шибко он ээээ... непонятный и без коментариев.
Особенно важны комментарии к используемым переменным-регистрам.

Более того регистры R30 и R31 рабочие. Скопируй в конце с регистра R30 в R28 например и обрезай его тем алгоритмом что я дал. Нельзя менять значение регистров R30 и R31 это сбивает работу ГСЧ.

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

Добавлено: Вс май 27, 2012 22:16:28
ChipKiller
самый простой способ что бы получить интервал ...... нужно из исходного значения вычитать число на 1 большее максимального значения интервала, до тех пор, пока остаток больше вычитаемого......

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

Добавлено: Вс май 27, 2012 22:34:25
мелкая
Alexeyslav писал(а):Алгоритм сама разрабатывала? По какому принципу он работает?
Классика - это длинный сдвиговый регистр с обратными связями.

В ЭТОТ алгоритм я еще не вкурил, шибко он ээээ... непонятный и без коментариев.
Особенно важны комментарии к используемым переменным-регистрам.

Более того регистры R30 и R31 рабочие. Скопируй в конце с регистра R30 в R28 например и обрезай его тем алгоритмом что я дал. Нельзя менять значение регистров R30 и R31 это сбивает работу ГСЧ.
попробовала как вы сказали и получился диапазон от 0-7, ANDI R28, 0xE0 если ставить значение 0x0F ничего не выводит!

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

MOV   R28,R30                  
		
			ANDI R28, 0xE0
loop:		CPI R28, 0x0A   
			BRLO next
	;		SUBI R28, 0x0A 
	;		rjmp loop

next:		SWAP  R28
			LSR   R28
		;	INC   R28            
			MOV   random,R28

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

Добавлено: Вс май 27, 2012 23:08:15
Alexeyslav
Хорошо, а отладка что дает? какое значение находится в R30 R31 на момент начала выполнения этого кусочка алгоритма?

Чтобы что-то существенное появилось в R30 и R31 алгоритм надо прокрутить несколько раз.

И до меня только что дошло что это очень фиговый и предсказуемый ГСЧ, поэтому у тебя в первом варианте и пошла "интерференция" в виде повторяющихся чисел.

Копируй все-таки в R28 содержимое регистра R31.

и правильно будет ANDI R28, 0x0F и никак не иначе. Эта строчка должна ограничивать количество бит, чтобы зря не крутится в цикле вычитая 10. Но вообще, её можно убрать вообще. Только тогда алгоритм будет прокручивать вычитание от 0 до 25 раз чтобы результат попал в нужные рамки. Вобщем-то это самый простейший но ресурсоемкий вариант реализации функции деления чисел.

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

Добавлено: Пн май 28, 2012 07:01:30
pyzhman
Оригинал линейного конгруентного генератора ПСЧ:

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

;
;X(i+1)= ( A*X(i) + B) mod 65536
;
;A= 77 (A mod 4= 1)
;B= 1 нечетное
;
;

random:
   MOV   R30,rnd_l   ;N=X
   MOV   R31,rnd_h

   LSL   rnd_l      ;*2
   ROL   rnd_h
   LSL   rnd_l      ;*4
   ROL   rnd_h

   ADD   R30,rnd_l   ;N=N+X*4
   ADC   R31,rnd_h

   LSL   rnd_l      ;*8
   ROL   rnd_h
   
   ADD   R30,rnd_l   ;N=N+X*8
   ADC   R31,rnd_h

   LSL   rnd_l      ;*16
   ROL   rnd_h
   LSL   rnd_l      ;*32
   ROL   rnd_h
   LSL   rnd_l      ;*64
   ROL   rnd_h

   ADD   R30,rnd_l   ;N=N+X*64  итого N= X*77
   ADC   R31,rnd_h

   ADIW   R30,1   ;N=N + 1

   MOV   rnd_l,R30   ;X=N
   MOV   rnd_h,R31

   ANDI   R31,0xE0   ;xxx0 0000
   CPI   R31,0xC0
   BRCC   random
                  ; 0...5,0 0000
   SWAP   R31
   LSR   R31
   INC   R31            ;0000 0,1...6
   MOV   rnd,R31

   RET

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

Добавлено: Вс июн 10, 2012 21:52:37
serg_svd
Прошу помощи с обработкой данных в АЦП ATtiny13A. Решил осваивать ассемблер, но не все с ходу получается. Итак, есть устройство на данном МК. Его задача, используя АЦП, сравнивать полученные значения с пороговыми и зажигать светодиоды.
С инициализацией МК, портов, АЦП справился. Особых трудностей не возникло. После инициализации АЦП, запускаем однократное преобразование с разрешением прерывания и переводом МК в режим ADC Noise Reduction. По окончании преобразования, уходим по вектору прерывания ADCCaddr (ADC Conversion Complete) на подпрограмму считывающую значения старшего и младшего регистров АЦП

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

adc_complete:	
		ldi zl, adcl			; Считываем младший байт
		ldi zh, adch			; Считываем старший байт
		reti				; возврат из пррывания
До этого момента в AVR симуляторе все проходит как и задумано.
Но дальше столкнулся с непониманием как мне сравнить эти считанные данные с пороговыми значениями, которые я посчитал заранее сам. То есть МК нужно только сравнивать с готовыми пороговыми значениями. Считать он ничего не будет сам. Нужен аналог команды If...Then...Else, но при этом надо как-то сравнивать двухбайтные числа.
Как пример, первое пороговое значение в десятичном виде равно 795 (АЦП 10 битный)
Вырвнивать результат по левому краю и переходить на 8 битный режим АЦП я не хочу. Снижается точность измерения напряжения с 0,014 В до 0,056 В. Меня это не устраивает

И вопрос №2, но он относится к вышеизложенному. Если я присвою метке значение

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

.EQU U1 = 795
то можно ли потом как-то работать с этой меткой напрямую и сравнивать с преобразованным значением? Это связано просто с удобством изменения пороговых значений. Или необходимо делить на старший и младший байт?

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

Добавлено: Вс июн 10, 2012 22:02:20
ChipKiller
serg_svd писал(а):но при этом надо как-то сравнивать двухбайтные числа.
... так же как и однобайтные - анализируя флаги...... смотри встроенную справку по ассемблеру в AVR Studio

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

Добавлено: Вс июн 10, 2012 22:19:09
ploop
serg_svd
Сравнивать двухбайтные числа просто: команда CPC (как и CP, только флаг переноса учитывает).
Ну например так:

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

.EQU my_const = 795 ; Наша константа
...
LDI R16, HIGH(my_const)
LDI R17, LOW(my_const)

CP ZH, R16
CPC  ZL, R17
ляляля

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

Добавлено: Вс июн 10, 2012 22:25:39
serg_svd
ChipKiller писал(а): ... так же как и однобайтные - анализируя флаги...... смотри встроенную справку по ассемблеру в AVR Studio
Я не совсем понял где это там искать?
Если можно поподробнее, я все же новичок в этом :facepalm:

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

Добавлено: Вс июн 10, 2012 22:39:15
Alexeyslav
Сравнивать числа несложно, достаточно вычесть пороговое из анализируемого и в зависимости от флагов делать то что нужно. Если результат равен нулю, после вычитания выставляется признак Z в статусе, далее можно использовать команду перехода BREQ, или лучше BRNE для перехода к следующей проверке.
Но тебе надо скорей всего проверять на условие БОЛЬШЕ или МЕНЬШЕ, используй другие признаки.
Например признак переноса C возникнет когда анализируемое число МЕНЬШЕ порога, поскольку в результате вычитания возникает заём. далее используй команды перехода BRxx в зависимости от необходимой логики.

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

Добавлено: Вс июн 10, 2012 23:09:46
serg_svd
Правильно и я понял ваши советы для преобразованного значения выше или равного пороговому?

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

.EQU U1 = 795
..........
ldi R17, high(u1)
ldi R18, low(u1)
cp zh, R17
cpc zl, R18
brsh blue_ON
Если все верно, то это лишь вершина айсберга. Далее мне нужно проверить следующие пороговые значения:
1) >=u2 AND <u1
2) >= u3 AND <u2
3) <u3

При этом u1>u2>u3. Подскажите пожалуйста как правильнее это реализовать и следует ли сразу из всех пороговых значений (констант) извлеч старший и младши байт в РАЗНЫЕ регистры (потребуется 6 регистров) Или можно сделать последовательный перебор условий и использовать при этом одни и теже 2 регистра (R17, R18)?

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

Добавлено: Вс июн 10, 2012 23:48:58
Alexeyslav
Последовательно проверить в цикле не получится, потому что нужны будут ведь разные действия а это означает что одна и та же команда перехода в цикле должна будет отправлять по разным адресам.

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

С индексом уже можно построить проверку условий типа CASE которая использует простую проверку на НЕРАВНО.

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

Добавлено: Пн июн 11, 2012 14:06:14
gyparr
привет всем, кто сидит в этой ветке)
у меня тупой вопрос, объясните плиз что делают эти строки

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

ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
ldi r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
Они взяты из проекта USI-SPI для аттини, так вот реально подогнать эти строки под работу SPI атмега48?

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

Добавлено: Пн июн 11, 2012 14:17:47
ChipKiller
gyparr писал(а):...что делают эти строки

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

ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
ldi r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
... формируют сигнал CLK

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

Добавлено: Пн июн 11, 2012 23:25:54
avreal
serg_svd писал(а):подпрограмму считывающую значения старшего и младшего регистров АЦП

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

adc_complete:	
		ldi zl, adcl			; Считываем младший байт
		ldi zh, adch			; Считываем старший байт
		reti				; возврат из пррывания
Это такой тест на внимательность форумчан? :tea:
Ну так не прошли :-)
Эта подпрограмма загружает константы, а не считывает порты.

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

Добавлено: Вт июн 12, 2012 11:40:29
ChipKiller
avreal писал(а):Это такой тест на внимательность форумчан? Ну так не прошли :-)
... да уж - перескакивая с AVR на другие МК легко забыть про инструкции in и out :)

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

Добавлено: Вт июн 12, 2012 22:06:04
serg_svd
avreal писал(а):Это такой тест на внимательность форумчан? :tea:
Ну так не прошли :-)
Эта подпрограмма загружает константы, а не считывает порты.
Теста никакого не было. Я пытаюсь учиться, но пока не знаю что выйдет из этого.
Команд много, в голове не все к сожалению удерживаются и тут я действительно упустил из виду команды in и out

Ну а насчет теста поясните пожалуйста мне вот такой пример

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

start:
sbic pinb, pinb0
cbi portb, pinb0
sbis pinb, pinb0
sbi portb, pinb0
rcall wait   	; Пауза
rjmp start
Это несложный код для переключения светодиода из одного сосстояния в другое. В AVR симуляторе работает без проблем. В железе не пробовал. Но вот в протеусе он не работает вообще (светодиод постоянно горит). Поясните пожалуйста почему?
А в AVR симуляторе заметил, что после выполнения команды cbi вначале пеерключается регистр порта PORTB.0, и только на следующем такте PINB.0. И только за счет этого этот кусок кода работает, позволяя "запутать" команду sbis, которая думает, что бит в порту еще установлен.
В книге по микроконтроллерам семейста ATtiny в разделе описания портов этому я пояснения не нашел.