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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

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

Сообщение Z_h_e »

Сразу бросилось в глаза вот это

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

out OCR0A+1, temp1
Что это такое??? В что то пишите в регистр SPMCSR?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

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

Сижу и думаю, что это за конструкции с +1? Постеснялся спросить, вдруг туплю. :) :oops:
Станислав
Реклама
Аватара пользователя
alex38779
Потрогал лапой паяльник
Сообщения: 386
Зарегистрирован: Чт окт 31, 2013 10:54:32
Контактная информация:

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

Сообщение alex38779 »

весь код
Спойлер

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

.include "tn13def.inc"

 .def temp = r16
 .def temp1 = r17
 
 ;для задержек
 .equ d_t1=255                
 .equ d_t2=255

 .DSEG
	t1: .byte 1
	t2: .byte 1

 .CSEG

 .ORG $00
	rjmp reset ; reset
	
 reset: 	 
	;стек
	ldi r16,RAMEND 
	out SPL,r16
	;загружаем данные
	ldi temp, d_t1
	sts t1, temp
	ldi temp, d_t2
	sts t2, temp
	;перефирия
	cli
	;кнопки
	andi temp, ~(1<<PB2 | 1<<PB3)
	out DDRB, temp
	andi temp, ~(1<<PB2 | 1<<PB3)
	out PORTB, temp
	;выходы
	ori temp, (1<<PB0 | 1<<PB1)
	out DDRB, temp
	andi temp, ~(1<<PB0 | 1<<PB1)
	out PORTB, temp
	;настройка timer t0 - fast pwm
	;TCCR0A
	in temp, TCCR0A
	ori temp, 1<<WGM00 | 1<<WGM01 | 1<<COM0A1 | 1<<COM0B1
	out TCCR0A, temp
	;TCCR0B, предделитель 64
	in temp, TCCR0B
	ori temp, 1<<CS01 | 1<<CS00
	out TCCR0B, temp
	;TCNT0
	;OCR0A
	ldi temp, 0
	out OCR0A, temp
	;OCR0B
	ldi temp, 60
	out OCR0B, temp
	sei
	;основная программа

 main:		
	lds temp, TCNT0
	lds temp1, TCNT0+1
	cpi r16,$10
	brcs ex1
	cpi r17, $01
	brcs ex1
	rcall led_pwm
 ex1:
	nop
	nop
	rjmp main

 ;плавный розжиг светодиода
 led_pwm:
	cli
	in temp, OCR0A
	in temp1, OCR0A+1
	inc temp
	out OCR0A, temp
	out OCR0A+1, temp1
	
	sei

	clr temp
	cli
	out TCNT0, temp
	sts TCNT0, temp
	sts TCNT0+1, temp
	sts TCNT0+2, temp
	sts TCNT0+3, temp
	sei
	ret

 .ESEG

Аватара пользователя
alex38779
Потрогал лапой паяльник
Сообщения: 386
Зарегистрирован: Чт окт 31, 2013 10:54:32
Контактная информация:

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

Сообщение alex38779 »

Это у DI так на сайте написано

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

OUT	TCNT0,R16	; Ноль в счетный регистр таймера
	STS	TCNT,R16	; Ноль в первый байт счетчика в RAM
	STS	TCNT+1,R16	; Ноль в второй байт счетчика в RAM
	STS	TCNT+2,R16	; Ноль в третий байт счетчика в RAM
	STS	TCNT+3,R16	; Ноль в первый байт счетчика в RAM
	SEI			; Разрешаем прерывания. 
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

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

Так у него переменные, объявленные в ОЗУ, а у вас регистры микроконтроллера....

TCNT0 и TCNT - совсем разные вещи. :)
Станислав
Реклама
Аватара пользователя
alex38779
Потрогал лапой паяльник
Сообщения: 386
Зарегистрирован: Чт окт 31, 2013 10:54:32
Контактная информация:

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

Сообщение alex38779 »

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

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

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

Так это же ШИМ или ВАМ. Я недавно это спрашивал на форуме здесь. Там ничего сложного.
http://radiokot.ru/forum/viewtopic.php?f=57&t=125263
Там внизу есть и про ШИМ... если память не изменяет.

Вроде у вас так и есть. Настраиваете таймер на ШИМ. В прерывании таймера меняете значение для сравнения увеличенное/уменьшенное на единицу. Каждое новое прерывание будет на выходе формировать импульсы с большим/меньшим коэффициентом заполнения.
Еще есть один момент. Все может происходить очень быстро, что не успеете увидеть. ))) Поэтому менять новое значение для сравнения (которое использует таймер) надо не в самом прерывании, а в главном цикле (например) с задержками большими.
Последний раз редактировалось СКАЗОЧНИК Вт мар 29, 2016 12:33:34, всего редактировалось 1 раз.
Станислав
Аватара пользователя
alex38779
Потрогал лапой паяльник
Сообщения: 386
Зарегистрирован: Чт окт 31, 2013 10:54:32
Контактная информация:

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

Сообщение alex38779 »

СКАЗОЧНИК

Вроде стало понятней.

Код сделал такой

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

	;основная программа
	ldi temp, 0
 main:
	cpi temp, 250
	brlo led_pwm
ex1:
	ldi temp,0
	rjmp main

 ;плавный розжиг светодиода
 led_pwm:
	cli
	inc temp
	out OCR0A, temp
	sei
	rjmp main
Ну и осциллограф показывает это
Изображение

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

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

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

Товарищи!
Подскажите, как сравнить две переменные двухбайтные, чтобы было можно определять больше/меньше?

Вот так будет правильно? Если перменная PERIODL (H) меньше, то переходим:

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

cp OFFL, PERIODL 
		cpc OFFH, PERIODH
		brlo OFF
Похоже наоборот. )))
Вот такая конструкция будет работать?

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

	Start:	

		cp  PERIODL, OFFL 
		cpc  PERIODH, OFFH
		brlo OFF

		cp  PERIODL, ONTumL
		cpc  PERIODH, ONTumH
		brsh ONT
		rjmp Start

	ONT: sbi PORTB, 0 	; Включаем туманки

		 cp  PERIODL, ONBlL
		 cpc  PERIODH, ONBLH
		 brsh ONB
		 rjmp Start

	ONB: sbi PORTB, 2	; Включаем ближний
		
		 rjmp Start

	OFF: cbi PORTB, 0
		 cbi PORTB, 2

	rjmp	Start	; Конец программы, переход на начало
Станислав
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Период обратно пропорционален скорости. Т.е. при скорости <5км/час период будет > и противотуманки должны быть выключены. А сравнения, вроде, правильные. Как-то так без гистерезиса.
Спойлер

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

.include "tn13def.inc"
;======================
.def	PERIODH=R20
.def	PERIODL=R21

.def	OFFH=R22
.def	OFFL=R23

.def	ONTumH=R24
.def	ONTumL=R25

.def	ONBlH=R26
.def	ONBlL=R27

   Start:   

	cp  PERIODL, OFFL
	cpc  PERIODH, OFFH	; скорость >5км/час
	BRSH OFF				; меньше, выключить всё
ONT:
	sbi PORTB, 0    ; Включаем туманки

	cp  PERIODL, ONBlL
	cpc  PERIODH, ONBlH
	BRSH	START	; скорость <40км/час, выходим
ONB:
	sbi PORTB, 2   ; скорость >40км/час,Включаем ближний
   rjmp   Start   ; Конец программы, переход на начало
OFF:
	cbi PORTB, 0
	cbi PORTB, 2
   rjmp   Start   ; Конец программы, переход на начало
.exit
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

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

Ну, у меня вроде также, только с гистерезисом. )) При 5 км/ч и меньше выключить все. При 15 км/ч включить туманки, при 40 км/ч включить второй ближний свет.
Станислав
Аватара пользователя
Starichok51
Модератор
Сообщения: 19048
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

СКАЗОЧНИК писал(а):Подскажите, как сравнить две переменные двухбайтные

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

cp R20, R16	; младшие байты
cpc R21, R17	; старшие байты
brlo error
это без символических имен, прямо указаны регистры.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

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

Вот, вроде все так, а работает даже, но почему-то наоборот. Но это я с ветвлениями не правильно намутил походу. Сейчас буду исправлять.
На машине проверили. Даже сохраняет значение скорости. Но включает нагрузку наоборот, когда меньше 5 км/ч скорость. :))) :)))

И всем СПАСИБО, что помогаете! :beer:
Станислав
Аватара пользователя
Starichok51
Модератор
Сообщения: 19048
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

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

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

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

А все. Разобрался. ))) Путаница у меня в голове возникла при сохранении и чтении старшего и младшего байта. А потом, как и указал, в ветвлениях. Там же наоборот получается, чем медленнее скорость, тем длиннее период! Значит число больше. Короче, точно сам накосячил. :)))

Если кому нужно, то выложу код и схему в какой-нибудь своей теме. Завтра на машине проверим и поставим ее. ))) Обязательно где-то надо отписаться будет.

Вопрос только небольшой. Что с чем сравнивается? Первое со вторым или наоборот?
Станислав
Аватара пользователя
Starichok51
Модератор
Сообщения: 19048
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

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

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

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

:))) Из первого вычитаем второе... :dont_know: Простите, туплю.
brlo Если результат вычитания отрицательный, т.е. первое меньше, чем второе, то переходим.

Другой вопрос. Как создать в АВРСтудио ЕЕПРОМ файл? А то я старые значения затер...
Станислав
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

СКАЗОЧНИК писал(а):Другой вопрос. Как создать в АВРСтудио ЕЕПРОМ файл? А то я старые значения затер...

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

.eseg

.org 0x01

EE_PARAM:
.db 0x55, 0xAA
.dw 0x55AA
Нулевой (первый) байт никогда не используйте. После каждого чтения-записи из\в EEPROM сбрасывайте указатель EEPROM в 0, чтобы он указывал на нулевой байт и при скачках питания не затер данные.
Спойлер

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

;*************************************************************************
;========== EEPROM ===================
;*************************************************************************

;Так как возможна случайная запись в EEPROM в случае сбоя питания, то:
;1 - В микроконтроллере включить контроль снижения напряжения питания. 
;2 - Первый (0x00) байт никогда не используется. 
;3 - После ресета обнулить указатель адреса EEPROM. 
;Решения для увеличения ресурса EEPROM:
;4 - Перед записью считывается байт, предназначенный для записи,
;проверяется на равенство с записываемым, если байты равны, то переход
;к записи следующего байта. 
;5 - В конце работы с EEPROM обнулить указатель адреса. 

#if (EEPROM==YES)

.macro Read_EEPROM
	ldix	@0 ; Указатель адреса EEPROM.
	ldiy	@1 ; Указатель адреса SRAM.
	ldi		CNT,@2 ; Количество байтов.
	rcall	_Read_EEPROM
.endmacro

_Read_EEPROM:
	sbic	EECR,EEWE
	rjmp	_Read_EEPROM
.ifdef EEARH
	out		EEARH,XH
.endif
	out		EEARL,XL
	sbi		EECR,EERE
	sbi		EECR,EERE
	in		EEDREG,EEDR
	st		Y+,EEDREG
	adiw	XL,1
	dec		Cnt
	brne	_Read_EEPROM
.ifdef EEARH
	out		EEARH,RClr
.endif
	out		EEARL,RClr
	ret

EERead:
	sbic	EECR,EEWE
	rjmp	EERead
	sbi		EECR,EERE
	sbi		EECR,EERE
	in		EEDREG,EEDR
	ret

EEWrite:
	sbic	EECR,EEWE
	rjmp	EEWrite
	out		EEDR,EEDREG
	sbi		EECR,EEMWE
	sbi		EECR,EEWE
	ret

Write_EEPROM:
	sbic	EECR,EEWE
	rjmp	Write_EEPROM
.ifdef EEARH
	out		EEARH,YH
.endif
	out		EEARL,YL
	ld		EEDREG,X
	out		EEDR,EEDREG
	sbi		EECR,EEMWE
	sbi		EECR,EEWE
	adiw	XL,1
	adiw	YL,1
	dec		Cnt
	brne	Write_EEPROM
.ifdef EEARH
	out		EEARH,RClr
.endif
	out		EEARL,RClr
	ret

Write_Param_EEPROM:
;	LDIX	Param_SRAM
;	LDIY	Param_EEPROM
;	ldi		Cnt,Param_Size
W_P_E_0:
	sbic	EECR,EEWE
	rjmp	W_P_E_0
.ifdef EEARH
	out		EEARH,YH
.endif
	out		EEARL,YL
	ld		r17,X
	rcall	EERead
	cp		r17,EEDREG
	breq	W_P_E_2
	mov		EEDREG,r17
W_P_E_1:
	sbic	EECR,EEWE
	rjmp	W_P_E_1
.ifdef EEARH
	out		EEARH,YH
.endif
	out		EEARL,YL
	rcall	EEWrite
W_P_E_2:
	adiw	XL,1
	adiw	YL,1
	dec		Cnt
	brne	W_P_E_0
.ifdef EEARH
	out		EEARH,RClr
.endif
	out		EEARL,RClr
	ret

; Считывание параметров.
Read_Write_Param:
;	LDIX	Param_SRAM
;	LDIY	Param_EEPROM
;	ldi		Cnt,Param_Size
;	rcall	Read_EEPROM
	ret

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

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

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

А, точно, есть же у меня в шапке программы такое место. )))) Спасибо.
Другой вопрос. А как по мне нужным адресам раскидать значения?

И у меня МК обучается, т.е. записывает эти значения сам в память. А здесь они будут жестко заданы?

З.Ы. Все. Увидел org.!!!!!!! Там начало адресов ЕЕПРОМ.

З.З.Ы. Блин, компилируется, но не записывает их. Чего-то еще надо? :roll: :oops:

З.З.З.Ы. ВСЕ. Всем спасибо. Разобрался. :music: :beer: :)))
Станислав
Аватара пользователя
Starichok51
Модератор
Сообщения: 19048
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

есть желание поделиться с уважаемой публикой результатами своих наработок.
это "комплект" подпрограмм деления и умножения.
в самих подпрограммах никакой "хитрости" нет. это вполне стандартные методы деления и умножения.
"хитрость" заключается в том, что подпрограммы СОГЛАСОВАНЫ.
то есть, результат одной подпрограммы служит входным числом для другой подпрограммы, и никакой передачи между регистрами не требуется.
Спойлер

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

;--- деление 16 бит в R21:R20 на 8 бит в R16 ---
;------ целая часть в R20, остаток в R21 -------
div_16_8_8_8:			; 16 битов (2 байта) делим на 8 битов (1 байт), получаем целую часть 8 битов (1 байт) и остаток 8 битов (1 байт)
ldi R18, 8				; делаем 8 циклов сдвига делимого/результата
div_16_8a:
lsl R20
rol R21
brcs div_16_8b			; если в результате сдвига влево появился перенос, то сразу же идем на вычитание, мимо сравнения
cp R21, R16
brcs div_16_8c			; если меньше, то пропускаем вычитание
div_16_8b:
sub R21,R16
sbr R20, 1
div_16_8c:
dec R18
brne div_16_8a
ret

;--- деление 32 бита в R23:R22:R21:R20 на 16 бит в R17:R16 ---
;--------- целая часть в R21:R20, остаток в R23:R22 ----------
div_32_16_16_16:		; 32 бита (4 байта) делим на 16 битов (2 байта), и получаем целую часть 16 битов (2 байта) и остаток 16 битов (2 байта)
ldi R18, 16				; делаем 16 циклов сдвига делимого/результата
div_32_16a:
lsl R20
rol R21
rol R22
rol R23
brcs div_32_16b			; если в результате сдвига влево появился перенос, то сразу же идем на вычитание, мимо сравнения
cp R22, R16
cpc R23, R17
brcs div_32_16c	
div_32_16b:			; если меньше, то пропускаем вычитание
sub R22,R16
sbc R23,R17
sbr R20, 1
div_32_16c:
dec R18
brne div_32_16a
ret

;--- умножение 16 бит в R21:R20 на 16 бит в R17:R16 ---
;----------- результат в R23:R22:R21:R20 --------------
mul_16x16_32:			; 16 битов (2 байта) умножаем на 16 битов (2 байта) и получаем в результате 32 бита (4 байта)
mov R18, R20
mov R19, R21
mul R21, R17			; старший * старший	'
movw R23:R22, R1:R0	; старшая пара результата
mul R18, R16			; младший * младший
movw R21:R20, R1:R0	; младшая пара результата
mul R19, R16			; старший * младший
add R21, R0
adc R22, R1
mul R18, R17			; младший * старший
add R21, R0
adc R22, R1
adc R23, R31
ret
для наглядности таких "цепочечных" вычислений приведу пару примеров из моего проекта в теме Imax B1, или тестер максимальной емкости батареек 18650

пример №1. подпрограмма калибровки результата измерения напряжения или тока.
Спойлер

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

;--- калибровка тока или напряжения ---
calibr_zamer:
mov R16, R4			; передадим замер в сомножитель
mov R17, R5			; в первом сомножителе (R21:R20) уже находится калибровчный коэффициент
rcall mul_16x16_32
ldi R16,  low(1024)
ldi R17, high(1024)		; делим на 1024, так как результат АЦП - 10-битный
rcall div_32_16_16_16
;--- округление числа после деления ---
okruglenie:
lsl R22				; сдвигаем остаток от деления влево - умножение на 2
rol R23
cp R22, R16			; сравниваем удвоенный остаток с делителем
cpc R23, R17
brlo end_okrug			; если меньше, то ничего не делаем
inc R20				; а если больше или равно, то прибавляем 1 к целой части результата деления
brne end_okrug
inc R21
end_okrug:
mov R4, R20
mov R5, R21			; вернем в регистры прокалиброванные ток или напряжение
ret
хорошо видно, что результат умножения сразу же является делимым для деления.
заодно можете видеть, как правильно нужно делать в программе округление результата по величина остатка.
округление организовано по стандартному правилу: если получилось 0,5 или более, то к целой части прибавляем 1.

пример №2. вывод секундомера на индикатор.
Спойлер

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

clr R23				; в R22:R21:R20 уже находится набранное время, очистим старший байт
ldi R16,  low(3600)
ldi R17, high(3600)		; после деления на 3600 в целой части результата получаеи количество часов, а в остатке получаем количество секунд
rcall div_32_16_16_16	; остаток меньше 3600
ldi R16, 10				; сразу же делим целую часть первого деления на 10,
rcall div_16_8_8_8		; и получаем в целой части результата десятки часов, а в остатке получаем единицы часов
ldi R18, '0'
add R18, R20			; десятки часов
rcall write_lcd
ldi R18, '0'
add R18, R21			; единицы часов
rcall write_lcd
ldi R18, ':'				; выведем двоеточие
rcall write_lcd
mov R21, R23			; переместим остаток в делимое
mov R20, R22
clr R23				; очистим старшие байты
clr R22
ldi R16,  low(600)		; после деления количества секунд на 600 получаем десятки минут,
ldi R17, high(600)
rcall div_32_16_16_16	; остаток меньше 600
ldi R18, '0'
add R18, R20			; десятки минут
rcall write_lcd
mov R21, R23
mov R20, R22			; переместим остаток первого деления в делимое
ldi R16, 60				; после деления на 60 получаем единицы минут
rcall div_16_8_8_8		; остаток меньше 60
ldi R18, '0'
add R18, R20			; единицы минут
rcall write_lcd
ldi R18, ':'				; выведем двоеточие
rcall write_lcd
mov R20, R21			; переместим остаток от последнего деления в делимое
clr R21				; очистим старший байт
ldi R16, 10				; после деления на 10
rcall div_16_8_8_8		; получаем в целой части результата десятки секунд, а в остатке получаем единицы секунд
ldi R18, '0'
add R18, R20			; десятки секунд
rcall write_lcd
ldi R18, '0'
add R18, R21			; единицы секунд
rcall write_lcd
end_vyvod_sekynd:
я постарался сделать очень подробные комментарии своих действий.
здесь тоже хорошо видно, что целая часть результата 32-битного деления сразу же служит делимым для 16-битного деления.

обратите внимание, что в случае 16-битного (2 байта) делимого для 32-битного деления нужно обнулить 2 старших байта в R23:R22.
а в случае 3-байтного делимого - обнулить только самый старший байт в R23.

еще замечу, что полного исходника, откуда взяты эти фрагменты, в указанной теме нет.

у меня пока все. спасибо за внимание...
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Ответить

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