Преобразование байта в три десятичные цифры

Обсуждаем контроллеры компании Atmel.
neitrino777
Родился
Сообщения: 19
Зарегистрирован: Вс сен 09, 2018 06:42:27

Преобразование байта в три десятичные цифры

Сообщение neitrino777 »

Всем привет ! прошу сильно меня не бить. Если создаю не нужную тему.
Искал я как то решение по отображению результатов работы ацп - на экране ТМ1637. И нужно было Преобразование байта в три десятичные цифры. Ответа не нашёл.
И просто сделал так. см. код. Не знаю насколько это оптимально - но мою задачу решает. Комментарии подробные писать не стал. На усмотрение модератора - можно удалить это.
; Редакция 27-05-19 - . Преобразуем 8 битное число в 3 десятичные цифры

;*******************************************
.include "tn13def.inc"
;****** РЕГИСТРЫ
.def ADCREZULT =r16 ; наши данные из ацп
.def dig0 =r17 ; результат для вывода на экран
.def dig1 =r18 ; результат для вывода на экран
.def dig2 =r19 ; результат для вывода на экран
rjmp RESET ;Reset Handle
reti ;External InterruptO Vector Address
reti ;External Interruptl Vector Address
reti ;Прерывание по переполнению таймера/счетчика 0
reti ;EE_READY_vect EEPROM готова
reti ;ANALOG_COMP_vect Аналоговый компаратор переключился
reti ;TIMER0_COMPA_vect Прерывание по сравнению, канал A таймера/счетчика 0
reti ;TIMER0_COMPB_vect Прерывание по сравнению, канал B таймера/счетчика 0
reti ;WDT_vect Сторожевой таймер (если используется в качестве источника прерывания)
reti ;ADC_vect Преобразование АЦП завершено


.cseg ; область команд
RESET:
clr dig0
clr dig1
clr dig2
clr ADCREZULT
ldi ADCREZULT,0xD3
povtor: subi ADCREZULT,100
brcs dalshe ;прекратить при установки флага переноса
inc dig2
rjmp povtor
dalshe: subi ADCREZULT,-100 ; компенсируем вычитание
povtor1: subi ADCREZULT,10
brcs dalshe2
inc dig1
rjmp povtor1
dalshe2: subi ADCREZULT,-10
povtor2: subi ADCREZULT,1
brcs dalshe3
inc dig0
rjmp povtor2
dalshe3: nop
nop
nop
Работа - продажа электронных компонентов. А для души - есть Ассемблер, дочка и сын.
Реклама
Аватара пользователя
SSkot
Друг Кота
Сообщения: 3500
Зарегистрирован: Пн июл 23, 2018 10:36:20
Откуда: Казань

Re: Преобразование байта в три десятичные цифры

Сообщение SSkot »

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

пример первый попавшийся

uint8_t hex = 0x11;
assert(((hex & 0xF0) >> 4) < 10); // More significant nybble is valid
assert((hex & 0x0F) < 10); // Less significant nybble is valid
int dec = ((hex & 0xF0) >> 4) * 10 + (hex & 0x0F);
ZZZ С Нами Бог ZZZ
Реклама
neitrino777
Родился
Сообщения: 19
Зарегистрирован: Вс сен 09, 2018 06:42:27

Re: Преобразование байта в три десятичные цифры

Сообщение neitrino777 »

спасибо за интерес. Здесь не преобразования bcd. Аппнот 204 - прочитал - не сильно внимательно. Но мою задачу он не решает быстро и просто. Я только учу ассемблер - ваш пример для меня
в диковинку - я таких команд не знаю. Пример у нас есть число 211 - нужно его вывести на экран ТМ1637 - там типа интерфейса I2C. Передаём весовые коды - обычные байты с кодом символа.
На нужно отдельно последовательно передать цифры 2---1---1. (начал изучать ацп attiny13 - интересно посмотреть на его показания в реальном времени)
Работа - продажа электронных компонентов. А для души - есть Ассемблер, дочка и сын.
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: Преобразование байта в три десятичные цифры

Сообщение ПростоНуб »

[uquote="neitrino777",url="/forum/viewtopic.php?p=3641598#p3641598"]Ответа не нашёл.[/uquote]
Вот один из самых эффективных алгоритмов для этой цели.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Ser60
Друг Кота
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Re: Преобразование байта в три десятичные цифры

Сообщение Ser60 »

Вот ещё способ: Допустим, нужно разложить однобайтовое число n на цифры. Обозначим их n1,n2,n3. Используем 8х8->16 перемножитель в AVR8.

1. Вычислить d = (n*205) >> 11. Умножение даст (в общем случае) 16-битное число, и на ассемблере сдвиг на 11 можно реализовать взяв старший байт полученного числа и сдвинув его вправо на 3 позиции.
Полученное число d равно целой части n / 10.
2. Вычислить n3 = n - d*10 - это будет младшая цифра.
3. Вычислить n1 = (d*26) >> 8, заменив сдвиг просто взятием старшего байта произведения.
4. Вычислить n2 = d - n1*10. Получим среднюю цифру.

Пример для n = 219:
1. d = (219*205) = 0xAF5F (в шестнадцатиричном обозначении). Старший байт = 0xAF = 175. Сдвинув его на 3 разряда вправо получим 21 (= целая часть 219/10)
2. n3 = 219 - 21*10 = 9 (последняя цифра)
3. n1 = (21*26) = 0x0222. Старший байт = 2 (первая цифра)
4. n2 = 21 = 2*10 = 1 (средняя цифра)
Реклама
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Преобразование байта в три десятичные цифры

Сообщение Ivanoff-iv »

это если мега... а тиня умножать не умеет
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Преобразование байта в три десятичные цифры

Сообщение akl »

Тоже неплохой алгоритм, давным давно взятый с электроникса. Легко адаптируется для разложения больших чисел.

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

BINBCD:
	LDS	R17,$70		; HEX IN

	CLR	R30		; BCD OUT 1'000,100
	CLR	R31		; BCD OUT 10,1

	LDI	R28,8
bin8_bcd3:
	subi r31,-0x33	;add 0x33
	sbrs r31, 3	;if carry to bit 3
	subi r31, 3	;subtract 3
	sbrs r31, 7	;if carry to bit 7
	subi r31, 0x30	;subtract 0x30

	subi r30,-0x33      ; \n" /*add 0x33*/
	sbrs r30, 3         ; \n" /*if carry to bit 3,*/
	subi r30, 3         ; \n" /*subtract 3*/
	sbrs r30, 7         ; \n" /*if carry to bit 7,*/
	subi r30, 0x30      ; \n" /*subtract 0x30*/

	LSL R17		;shift input*/

	rol r31
	rol r30		; \n" /*shift out buffer*/

	dec R28		;\n"
	brne bin8_bcd3	;repeat for all bits*/

	RET
Добавлено after 6 minutes 55 seconds:
neitrino777 Замечу, что в коде ниже можно просто остаток единиц занести в dig0

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

povtor2:	MOV	dig0,ADCREZULT
; subi ADCREZULT,1
;brcs dalshe3
;inc dig0
;rjmp povtor2
dalshe3: nop
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Преобразование байта в три десятичные цифры

Сообщение Engineer_Keen »

Не знаю как для других вариантов преобразования, но для варианта "байт->3 десятичные цифры", оптимальным является именно вариант из первого поста, т.е. последовательное вычитание 100,10, с учетом последнего замечания akl (остаток единиц, получается автоматом). Его преимущество и в размере (меньше на полтора десятка байт) и в скорости выполнения.

Достоинство метода "сдвиг-сложение с 3" (double-dabble), в том, что этот алгоритм выполняется всегда за почти одинаковое время, например для 16МГц это примерно 8мкс, не зависимо от числа на входе. Дело конечно в заранее известном количестве циклов, но при этом занята +1 переменная под счетчик цикла, и в конце еще надо распихивать нибблы, в отдельные байты, так как там в каждом байте результата получается по 2 разряда десятичного числа.

Для метода последовательных вычитаний время выполнения от 750нс (на входе 0), до 4мкс (на входе 199, максимальное количество вычитаний), и каждый байт в итоге уже содержит один разряд десятичного числа.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Преобразование байта в три десятичные цифры

Сообщение akl »

Метод последовательного вычитания быстр и начинает проигрывать при преобразовании больших чисел, когда вес оных превышает возможности ассемблера (4 байта). Пользуюсь и тем и другим.
Например, преобразование 40 разрядного числа только на старшей части регистрового файла AVR.
Спойлер

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

	LDS	R16,$70
	LDS	R17,$71
	LDS	R18,$72
	LDS	R19,$73		; HEX IN
	LDS	R20,$74

	CLR	R25		; BCD OUT 10'000'000'000'000,1'000'000'000'000
	CLR	R26		; BCD OUT 100'000'000'000,10'000'000'000
	CLR	R27		; BCD OUT 1'000'000'000,100'000'000
	CLR	R28		; BCD OUT 10'000'000,1'000'000
	CLR	R29		; BCD OUT 100'000,10'000
	CLR	R30		; BCD OUT 1'000,100
	CLR	R31		; BCD OUT 10,1

	LDI	R24,40
bin40bcd13:
	subi r31,-0x33	;add 0x33
	sbrs r31, 3	;if carry to bit 3
	subi r31, 3	;subtract 3
	sbrs r31, 7	;if carry to bit 7
	subi r31, 0x30	;subtract 0x30

	subi r30,-0x33      ; \n" /*add 0x33*/
	sbrs r30, 3         ; \n" /*if carry to bit 3,*/
	subi r30, 3         ; \n" /*subtract 3*/
	sbrs r30, 7         ; \n" /*if carry to bit 7,*/
	subi r30, 0x30      ; \n" /*subtract 0x30*/

	subi r29,-0x33       ;\n" /*add 0x33*/
	sbrs r29, 3          ;\n" /*if carry to bit 3,*/
	subi r29, 3          ;\n" /*subtract 3*/
	sbrs r29, 7          ;\n" /*if carry to bit 7,*/
	subi r29, 0x30       ;\n" /*subtract 0x30*/

	subi r28,-0x33       ;\n" /*add 0x33*/
	sbrs r28, 3          ;\n" /*if carry to bit 3,*/
	subi r28, 3          ;\n" /*subtract 3*/
	sbrs r28, 7          ;\n" /*if carry to bit 7,*/
	subi r28, 0x30       ;\n" /*subtract 0x30*/

	subi r27,-0x33       ;\n" /*add 0x33*/
	sbrs r27, 3          ;\n" /*if carry to bit 3,*/
	subi r27, 3          ;\n" /*subtract 3*/
	sbrs r27, 7          ;\n" /*if carry to bit 7,*/
	subi r27, 0x30       ;\n" /*subtract 0x30*/

	subi r26,-0x33       ;\n" /*add 0x33*/
	sbrs r26, 3          ;\n" /*if carry to bit 3,*/
	subi r26, 3          ;\n" /*subtract 3*/
	sbrs r26, 7          ;\n" /*if carry to bit 7,*/
	subi r26, 0x30       ;\n" /*subtract 0x30*/

	subi r25,-0x33       ;\n" /*add 0x33*/
	sbrs r25, 3          ;\n" /*if carry to bit 3,*/
	subi r25, 3          ;\n" /*subtract 3*/
	sbrs r25, 7          ;\n" /*if carry to bit 7,*/
	subi r25, 0x30       ;\n" /*subtract 0x30*/

	lsl R20
	rol R19
	rol R18
	rol R17		;shift input*/
	rol R16

	rol r31
	rol r30
	rol r29
	rol r28		; \n" /*shift out buffer*/
	rol r27
	rol r26
	rol r25
  
	dec R24		;\n"
	brne bin40bcd13	;repeat for all bits*/

       RET
neitrino777
Родился
Сообщения: 19
Зарегистрирован: Вс сен 09, 2018 06:42:27

Re: Преобразование байта в три десятичные цифры

Сообщение neitrino777 »

test

Добавлено after 13 minutes 21 second:
Спасибо всем за предложенные варианты. Особое спасибо за подсказку after 6. Буду дальше изучать тиньку - что из нее можно выжать. Для моих экспериментов её более чем достаточно.
Работа - продажа электронных компонентов. А для души - есть Ассемблер, дочка и сын.
AlexVi
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Вт сен 19, 2017 14:16:15

Re: Преобразование байта в три десятичные цифры

Сообщение AlexVi »

[uquote="akl",url="/forum/viewtopic.php?p=3641961#p3641961"]Например, преобразование 40 разрядного числа...[/uquote] Знакомые строки :)
Пользуясь случаем, еще раз спасибо akl за конкурсный LC-метр, в особенности за выложенные исходники. До сих пор приятно в них покопаться и переиначить на очередное устройство. Два здесь публиковались, одно на конкурсе даже до 5 места (или 6, не припомню) добралось. Создается и третье, вполне себе оригинальное. Кроме того, те исходники - отличный образец многоразрядной арифметики. :beer:
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Преобразование байта в три десятичные цифры

Сообщение Demiurg »

Спойлер

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

;-------------------------------------------------------------------------
#define BCD YES
;===================

.macro	ldx
	ldi		XH,High(@0)
	ldi		XL,Low(@0)
.endmacro

.macro	ldy
	ldi		YH,High(@0)
	ldi		YL,Low(@0)
.endmacro

.macro	ldz
	ldi		ZH,High(@0)
	ldi		ZL,Low(@0)
.endmacro

;-------------------------------------------------------------------------
#define tab_h(x) HIGH(x), LOW(x)
#define tab_l(x) LOW(x), HIGH(x)
;-------------------------------------------------------------------------

;----------------------------- Отладка -----------------------------------
   rcall Clr_Hex_Dex_Buffer

   ldi   r16, 199
   rcall Hex_Dec_8_Bit

   rcall Clr_Hex_Dex_Buffer

   ldi   r16, LOW (64999)
   ldi   r17, HIGH (64999)
   rcall Hex_Dec_16_Bit
;-------------------------------------------------------------------------

/************************************************************************/
#if (BCD == YES)

.dseg

HEX_DEC_BUFFER:
.equ  HEX_DEC_BUFFER_LENGHT = 5
.byte HEX_DEC_BUFFER_LENGHT


.cseg

Clr_Hex_Dex_Buffer:
   ldx   HEX_DEC_BUFFER
   clr   r16
   ldi   r17, HEX_DEC_BUFFER_LENGHT
Clr_Hex_Dex_Buffer_Cycle:
   st    X+, r16
   dec   r17
   brne  Clr_Hex_Dex_Buffer_Cycle
   ret

//==================
// r16 - hex data
// r17 - вычитаемое число из таблицы
// r18 - cnt_1
// r19 - cnt_2

Hex_Dec_8_Bit:
   ldx      HEX_DEC_BUFFER
   ldz      TAB_HEX_DEC_8_BIT*2
   ldi      r18, 2
Hex_Dec_8_Bit_Cycle_1:
   lpm      r17, Z+

   ldi      r19, -1
Hex_Dec_8_Bit_Cycle_2:
   inc      r19
   sub      r16, r17
   brsh     Hex_Dec_8_Bit_Cycle_2
   add      r16, r17
   ori      r19, 0x30

   st       X+, r19
   dec      r18
   brne     Hex_Dec_8_Bit_Cycle_1
   ori      r16,0x30
   st       X+, r16
Hex_Dec_8_Bit_End:
   ret
//------------------------------------------------------------------------

//------------------------------------------------------------------------
TAB_HEX_DEC_8_BIT:
.db   100, 10
//==================

//==================
// r16, r17 - hex data
// r18, r19 - вычитаемое число из таблицы
// r20 - cnt_1
// r21 - cnt_2

Hex_Dec_16_Bit:
   ldx      HEX_DEC_BUFFER
   ldz      TAB_HEX_DEC_16_BIT*2
   ldi      r20, 4
Hex_Dec_16_Bit_Cycle_1:
   lpm      r18, Z+
   lpm      r19, Z+

   ldi      r21, -1
Hex_Dec_16_Bit_Cycle_2:
   inc      r21
   sub      r16, r18
   sbc      r17, r19
   brsh     Hex_Dec_16_Bit_Cycle_2
   add      r16, r18
   adc      r17, r19
   ori      r21, 0x30

   st       X+, r21
   dec      r20
   brne     Hex_Dec_16_Bit_Cycle_1
   ori      r16,0x30
   st       X+, r16
Hex_Dec_16_Bit_End:
   ret
//------------------------------------------------------------------------

//------------------------------------------------------------------------
TAB_HEX_DEC_16_BIT:
.db   tab_l (10000)
.db   tab_l (1000)
.db   tab_l (100)
.db   tab_l (10)
//==================

#endif
/************************************************************************/
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: Преобразование байта в три десятичные цифры

Сообщение B@R5uk »

[uquote="Engineer_Keen",url="/forum/viewtopic.php?p=3641953#p3641953"]Не знаю как для других вариантов преобразования, но для варианта "байт->3 десятичные цифры", оптимальным является именно вариант из первого поста, т.е. последовательное вычитание 100,10, с учетом последнего замечания akl (остаток единиц, получается автоматом). Его преимущество и в размере (меньше на полтора десятка байт) и в скорости выполнения.[/uquote]
Долго мучил голову в попытках опровергнуть это утверждение. Этого, конечно, сделать не удалось, но в результате всех мучений родилось такое вот извращение:

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

;==============
.def    cntr    =   r16
.def    dig1    =   r17
.def    dig2    =   r18
.def    dig3    =   r19
.def    sbtr    =   r20
;==============
                ;   Время выполнения 65 тактов
                ldi     dig3,   0xFF    ;   Преобразуемое в десятичный вид число
                ldi     cntr,   0x02    ;   Выделяется 2 бита первой цифры
                ldi     sbtr,   0xC8    ;   100 * 2 ^ (2 - 1)
                clr     dig1            ;   Подготовка искомой цифры
loop_1:         lsl     dig1            ;   Удвоение искомой цифры
                sub     dig3,   sbtr    ;   Выделение очередного бита
                brcs    loop_1a
                inc     dig1            ;   Бит 1: увеличить искомую цифру
loop_1a:        brcc    loop_1b
                add     dig3,   sbtr    ;   Бит 0: восстановить аргумент
loop_1b:        lsr     sbtr            ;   Значение следующего бита искомой цифры
                dec     cntr
                brne    loop_1          ;   Повтор для всех битов
                ldi     cntr,   0x04    ;   Выделяется 4 бита второй цифры
                ldi     sbtr,   0x50    ;   10 * 2 ^ (4 - 1)
                clr     dig2            ;   Подготовка искомой цифры
loop_2:         lsl     dig2            ;   Удвоение искомой цифры
                sub     dig3,   sbtr    ;   Выделение очередного бита
                brcs    loop_2a
                inc     dig2            ;   Бит 1: увеличить искомую цифру
loop_2a:        brcc    loop_2b
                add     dig3,   sbtr    ;   Бит 0: восстановить аргумент
loop_2b:        lsr     sbtr            ;   Значение следующего бита искомой цифры
                dec     cntr
                brne    loop_2          ;   Повтор для всех битов
                ;   Третья цифра получается автоматически
;==============
Основная идея была в том, что код топикстартера имеет линейную сложность и её можно улучшить до логарифмической небольшим усложнением кода. Деление с остатком методом вычитания заменяется побитовым делением с остатком. Однако, усложнение приводит к большей константе перед логарифмом (по сравнению с константой перед линейным членом в "примитивном" алгоритме) и, поскольку под логарифмом стоит число от 1 до 10 (то есть слишком маленькое, чтобы была принципиальная разница между аргументом логарифма и его значением), в результате ускорения добиться не получается.

Думаю, все остальные алгоритмы (какими бы они не были) обладают той же проблемой даже при больших разрядностях исходного числа. Вот, если бы мы пользовались бы не 10-ой системой, а какой-нибудь 24-ой или ещё лучше 60-ой, то было бы совсем другое дело!!!

На всякий случай модифицированный код топикстартера. Время выполнения варьируется от 11 тактов (для байтов, меньших 10) до 61 такта (для байтов, начинающихся на 19).

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

;==============
.def    dig1    =   r17
.def    dig2    =   r18
.def    dig3    =   r19
;==============
                ;   Время выполнения 11 + 5 * {сумма первой и второй цифр} тактов
                ldi     dig3,   0xFF    ;   Преобразуемое в десятичный вид число
                clr     dig1            ;   Подготовка первой цифры
loop_1:         subi    dig3,   0x64    ;   Цикл вычитания 100
                brcs    loop_1a         ;   Окончание цикла, когда остаток меньше 100
                inc     dig1            ;   Инкремент первой цифры
                rjmp    loop_1
loop_1a:        subi    dig3,   0x9C    ;   Коррекция остатка
                clr     dig2            ;   Подготовка второй цифры
loop_2:         subi    dig3,   0x0A    ;   Цикл вычитания 10
                brcs    loop_2a         ;   Окончание цикла, когда остаток меньше 10
                inc     dig2            ;   Инкремент второй цифры
                rjmp    loop_2
loop_2a:        subi    dig3,   0xF6    ;   Коррекция остатка, являющ. третьей цифрой
;==============
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15561
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Преобразование байта в три десятичные цифры

Сообщение BOB51 »

Если честно "стандартное преобразование" данных 0-99 (типовые часики, считалки)
наиболее просто решаются табличным способом.
А уже куда побольше - за сотню - там математика.
Однако это уже потребует заготовок не только на один байт.
Ибо 999 это 0х3E7 - а 3 знакоместа подразумевают 0-999.
8)
Аватара пользователя
Starichok51
Модератор
Сообщения: 19049
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Преобразование байта в три десятичные цифры

Сообщение Starichok51 »

вот еще один немудреный алгоритм.
исходное число в R10.

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

clr R12
ldi R26, 100
test_100:
cp R10, R26
brcs test_10_1
sub R10, R26
inc R12
rjmp test_100
test_10_1:
ldi R26, 10
test_10:
cp R10, R26
brcs end_test
sub R10, R26
inc R11
rjmp test_10
end_test:
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Преобразование байта в три десятичные цифры

Сообщение akl »

Нужно почистить ещё и регистр десятков R11.

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

	CLR	R11

	clr R12
	ldi R26, 100
test_100:
	cp R10, R26
	brcs test_10_1
	sub R10, R26
	inc R12
	rjmp test_100
test_10_1:
	ldi R26, 10
test_10:
	cp R10, R26
	brcs end_test
	sub R10, R26
	inc R11		; при входе этот регистр должен очищаться
	rjmp test_10
end_test:
	RJMP	PC
Аватара пользователя
Starichok51
Модератор
Сообщения: 19049
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Преобразование байта в три десятичные цифры

Сообщение Starichok51 »

в данном случае (с одним байтом) да, нужно очистить R11.
это я взял свой кусок текста, где вычитались тысячи и сотни, и исходное число было в R10 и R11.
поспешил скопировать и вставить, а про очистку R11 забыл...
и после вычитания сотен R11 сам очистится, предварительно его чистить не надо.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Frogfot
Мучитель микросхем
Сообщения: 443
Зарегистрирован: Ср окт 19, 2011 08:48:27
Откуда: Мать городов русских

Re: Преобразование байта в три десятичные цифры

Сообщение Frogfot »

[uquote="akl",url="/forum/viewtopic.php?p=3641961#p3641961"]Метод последовательного вычитания быстр и начинает проигрывать при преобразовании больших чисел, когда вес оных превышает возможности

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

bin40bcd13:
subi r31,-0x33 ;add 0x33
sbrs r31, 3 ;if carry to bit 3
subi r31, 3 ;subtract 3
sbrs r31, 7 ;if carry to bit 7
subi r31, 0x30 ;subtract 0x30
[/uquote]
Кто подскажет, как работает этот метод - добавляем к ниблу число 3, и если нибл становится больше 7, то отнимаем 3, а если не больше 7, то не отнимаем ???
Хорошему коту и в декабре - март :)
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Преобразование байта в три десятичные цифры

Сообщение Demiurg »

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

Re: Преобразование байта в три десятичные цифры

Сообщение akl »

[uquote="Frogfot",url="/forum/viewtopic.php?p=3655792#p3655792"]Кто подскажет, как работает этот метод - добавляем к ниблу число 3, и если нибл становится больше 7, то отнимаем 3, а если не больше 7, то не отнимаем ???[/uquote]Не забывайте, что преобразование идет побитно в цикле. Для лучшего понимания можно в симуляторе погонять преобразование байта в двоично-десятичный код.

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

;Преобразование 8bin-3dec
BINBCD:
	LDS	R17,$70		; HEX IN

	CLR	R30		; BCD OUT 1'000,100
	CLR	R31		; BCD OUT 10,1

	LDI	R28,8
bin8_bcd3:
	subi r31,-0x33	;add 0x33
	sbrs r31, 3	;if carry to bit 3
	subi r31, 3	;subtract 3
	sbrs r31, 7	;if carry to bit 7
	subi r31, 0x30	;subtract 0x30

	subi r30,-0x33      ; \n" /*add 0x33*/
	sbrs r30, 3         ; \n" /*if carry to bit 3,*/
	subi r30, 3         ; \n" /*subtract 3*/
	sbrs r30, 7         ; \n" /*if carry to bit 7,*/
	subi r30, 0x30      ; \n" /*subtract 0x30*/

	LSL R17		;shift input*/

	rol r31
	rol r30		; \n" /*shift out buffer*/

	dec R28		;\n"
	brne bin8_bcd3	;repeat for all bits*/

	RJMP	BINBCD
.EXIT
Ответить

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