Преобразование байта в три десятичные цифры
- КРАМ
- Друг Кота
- Сообщения: 25234
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Преобразование байта в три десятичные цифры
[uquote="Starichok51",url="/forum/viewtopic.php?p=3658421#p3658421"]не обязательно, что это будут ЧАСЫ.[/uquote]
Я про часы говорил, как про особый случай. Только для часов С АВТОНОМНЫМ ПИТАНИЕМ имеет смысл сокращение КОЛИЧЕСТВА МАШЦИКЛОВ на такое преобразование. Каждый машинный цикл - это микродоза энергии от источника. То есть часы должны в основном находится в SLEEP-е. Тогда время работы от источника будет определяться саморазрядом этого источника.
Я про часы говорил, как про особый случай. Только для часов С АВТОНОМНЫМ ПИТАНИЕМ имеет смысл сокращение КОЛИЧЕСТВА МАШЦИКЛОВ на такое преобразование. Каждый машинный цикл - это микродоза энергии от источника. То есть часы должны в основном находится в SLEEP-е. Тогда время работы от источника будет определяться саморазрядом этого источника.
- Реклама
- Starichok51
- Модератор
- Сообщения: 19049
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Преобразование байта в три десятичные цифры
да понял я тебя. но это очень особый случай, когда нужно экономить питания.
а я рассказал про самый общий случай, когда экономить питание не надо и спешить некуда.
а я рассказал про самый общий случай, когда экономить питание не надо и спешить некуда.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Преобразование байта в три десятичные цифры
Раскурил я предложенную выше статью, а именно раздел 5 "Деление на 10 сдвигами и сложениями". Пошаманив, придумал код для деления байта с остатком на 10 со своими собственными оптимизациями. В частности, корректировку остатка и частного я перенёс в середину процедуры до вычисления остатка, поэтому корректировать надо только частное. Это позволяет сэкономить 2, а то и все 4 такта процессора.
Спойлер
Код: Выделить всё
;==============
.def val = r16
.def rem = r17
.def tmp = r18
;==============
; Процедура осуществляет деление байта на 10 с остатком
; Размер: 38 байт
; Время: 19 тактов
; Регистры: 3 штуки
ldi val, 0xAB ; Исходная величина
mov rem, val ; Подготовка к вычислению остатка
lsr val ; Рассчёт
mov tmp, val ; целой
lsr tmp ; части
add val, tmp ; произведения
mov tmp, val ; величины
swap tmp ; 0.8 (10) = 0.1100 1100 1100... (2)
andi tmp, 0x0F ; на исходный
add val, tmp ; байт
inc val ; Коррекция рассчитанного произведения.
sbrc val, 7 ; Эти две строчки коррекции можно
inc val ; убрать, если исходный байт <= 169
andi val, 0xF8 ; Искомое частное, умноженное на 8
sub rem, val ; Вычисление искомого
lsr val ; остатка (вычитание)
lsr val ; одновременно
sub rem, val ; с искомым частным
lsr val ; (деление на 8)
; Конец процедуры- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Преобразование байта в три десятичные цифры
Итак, процедуры байт в строку файнал эдишн. С сохранением в оперативку (как заказывали). Три варианта (дабл-дабл в пролёте за неадекватностью).
Табличный метод
Размер: 142 байта
Время: 22...26 тактов
Регистры: 2 штуки + Y + Z
Метод деления на 10 сдвигами и сложением
Размер: 66 байт
Время: 36 тактов
Регистры: 3 штуки + Y
Метод циклов с вычитаниями
Размер: 36 байт
Время: 19...69 тактов
Регистры: 2 штуки + Y
Лично мне нравится метод деления на 10 с остатком. Во-первых за константное время выполнения, а во-вторых за неординарное битовое шаманство. =D Надо бы попробовать реализовать деление на 10 для двух и трёх байт.
Табличный метод
Размер: 142 байта
Время: 22...26 тактов
Регистры: 2 штуки + Y + Z
Спойлер
Код: Выделить всё
;==============
.def tmp1 = r16
.def tmp2 = r17
;==============
; Процедура преобразует байт в строку цифр
; табличным методом и сохраняет её в памяти
; Размер: 142 байта
; Время: 22...26 тактов
; Регистры: 2 штуки + Y + Z
ldi ZL, 0x63 ; Величина, преобразуемая в десятичный вид
ldi ZH, HIGH(2 * t10div) ; Таблица разложения чисел 0..99
ldi YH, 0x00 ; Адрес в ОЗУ
ldi YL, 0x60 ; для сохранения результата
clr tmp1 ; Инициализация первой цифры
subi ZL, 0x64 ; Определение
brcs branch ; первой
inc tmp1 ; цифры
subi ZL, 0x64 ; байта
brcs branch ; методом
inc tmp1 ; последовательных
subi ZL, 0x64 ; вычитаний
branch: subi ZL, 0x9C ; величины 100
st Y+, tmp1 ; Сохранение 1-ой цифры
lpm tmp1, Z ; Загрузка десятичного представления остатка
mov tmp2, tmp1 ; Разделение
swap tmp1 ; остатка на две
andi tmp1, 0x0F ; десятичные
andi tmp2, 0x0F ; цифры
st Y+, tmp1 ; Сохранение 2-ой цифры
st Y+, tmp2 ; Сохранение 3-ей цифры
; Конец процедуры
;==============
; Таблица преобразования величин диапазона 0..99 в десятичные цифры
.org 0x0300
t10div: .dw 0x0100,0x0302,0x0504,0x0706,0x0908,0x1110,0x1312,0x1514,0x1716,0x1918
.dw 0x2120,0x2322,0x2524,0x2726,0x2928,0x3130,0x3332,0x3534,0x3736,0x3938
.dw 0x4140,0x4342,0x4544,0x4746,0x4948,0x5150,0x5352,0x5554,0x5756,0x5958
.dw 0x6160,0x6362,0x6564,0x6766,0x6968,0x7170,0x7372,0x7574,0x7776,0x7978
.dw 0x8180,0x8382,0x8584,0x8786,0x8988,0x9190,0x9392,0x9594,0x9796,0x9998
;==============Размер: 66 байт
Время: 36 тактов
Регистры: 3 штуки + Y
Спойлер
Код: Выделить всё
;==============
.def val = r16
.def tmp1 = r17
.def tmp2 = r18
;==============
; Процедура преобразует байт в строку цифр методом деления на 10
; с остатком сдвигами и сложениями и сохраняет её в памяти
; Размер: 66 байт
; Время: 36 тактов
; Регистры: 3 штуки + Y
ldi val, 0xC7 ; Величина, преобразуемая в десятичный вид
ldi YH, 0x00 ; Адрес в ОЗУ
ldi YL, 0x60 ; для сохранения результата
clr tmp1 ; Инициализация первой цифры
cpi val, 0x64 ; Определение
brcs PC+2 ; первой
inc tmp1 ; цифры
brcs PC+2 ; байта
subi val, 0x64 ; методом
cpi val, 0x64 ; последовательных
brcs PC+2 ; вычитаний
inc tmp1 ; из него
brcs PC+2 ; величины
subi val, 0x64 ; 100
st Y+, tmp1 ; Сохранение 1-ой цифры
; Деление с остатком на 10
mov tmp1, val ; Подготовка к вычислению остатка
lsr val ; Расчёт
mov tmp2, val ; целой
lsr tmp2 ; части
add val, tmp2 ; произведения
mov tmp2, val ; величины
swap tmp2 ; 0.8 (10) = 0.1100 1100 1100... (2)
andi tmp2, 0x0F ; на исходный
add val, tmp2 ; байт
inc val ; Коррекция рассчитанного произведения
andi val, 0xF8 ; Искомое частное, умноженное на 8
sub tmp1, val ; Вычисление искомого
lsr val ; остатка (вычитание)
lsr val ; одновременно
sub tmp1, val ; с искомым частным
lsr val ; (деление на 8)
st Y+, val ; Сохранение 2-ой цифры
st Y+, tmp1 ; Сохранение 3-ей цифры
; Конец процедуры
;==============Размер: 36 байт
Время: 19...69 тактов
Регистры: 2 штуки + Y
Спойлер
Код: Выделить всё
;==============
.def val = r16
.def tmp = r17
;==============
; Процедура преобразует байт в строку цифр методом последовательных
; вычитаний степеней 10 в циклах и сохраняет её в памяти
; Размер: 36 байт
; Время: 19...69 тактов
; Регистры: 2 штуки + Y
ldi val, 0xC7 ; Величина, преобразуемая в десятичный вид
ldi YH, 0x00 ; Адрес в ОЗУ
ldi YL, 0x60 ; для сохранения результата
clr tmp ; Инициализация 1-ой цифры
loop100: subi val, 0x64 ; Цикл вычитания 100
brcs loop100end ; Конец цикла, если остаток был меньше 100
inc tmp ; Инкремент 1-ой цифры
rjmp loop100 ; Повтор цикла
loop100end: subi val, 0x9C ; Коррекция остатка
st Y+, tmp ; Сохранение 1-ой цифры
clr tmp ; Инициализация 2-ой цифры
loop10: subi val, 0x0A ; Цикл вычитания 10
brcs loop10end ; Конец цикла, если остаток был меньше 10
inc tmp ; Инкремент 2-ой цифры
rjmp loop10 ; Повтор цикла
loop10end: subi val, 0xF6 ; Коррекция остатка
st Y+, tmp ; Сохранение 2-ой цифры
st Y+, val ; Сохранение 3-ей цифры
; Конец процедуры
;==============- Starichok51
- Модератор
- Сообщения: 19049
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Преобразование байта в три десятичные цифры
ты для примера взял число 199, меньше 200. а число может быть и 255. и для всего диапазона чисел в одном байте не будет константного времени.B@R5uk писал(а):мне нравится метод деления на 10 с остатком. Во-первых за константное время выполнения
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Реклама
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Преобразование байта в три десятичные цифры
[uquote="Starichok51",url="/forum/viewtopic.php?p=3659009#p3659009"]не будет константного времени.[/uquote]Чего это вдруг? Условные переходы в начале действуют как команды SBRC/SBRS, и программа выполняется линейно. И потом, в симуляторе я тестил не только одно значение байта.
Re: Преобразование байта в три десятичные цифры
Когда нужно очень быстро преобразовать байт. Вариант полного табличного преобразования для TIC107. 23 такта и готово.
Спойлер
Код: Выделить всё
SIMVOL:
LDI ZH,HIGH(T_ZNAK*2)
LDI ZL,LOW(T_ZNAK*2)
CLR R1
LDS R2,$70 ; преобразуемое значение
LSL R2
ROL R1
LSL R2
ROL R1 ; R1,R2x4
ADD ZL,R2
ADC ZH,R1
LPM R5,Z+
LPM R6,Z+
LPM R7,Z+
LPM R8,Z
RJMP SIMVOL
;*************************************************
T_ZNAK:
.DB $20,$20,$20,$B0
.DB $20,$20,$20,$B1
.DB $20,$20,$20,$B2
.DB $20,$20,$20,$B3
.DB $20,$20,$20,$B4
.DB $20,$20,$20,$B5
.DB $20,$20,$20,$B6
.DB $20,$20,$20,$B7
.DB $20,$20,$20,$B8
.DB $20,$20,$20,$B9
.DB $20,$20,$B1,$B0
.DB $20,$20,$B1,$B1
.DB $20,$20,$B1,$B2
.DB $20,$20,$B1,$B3
.DB $20,$20,$B1,$B4
.DB $20,$20,$B1,$B5
.DB $20,$20,$B1,$B6
.DB $20,$20,$B1,$B7
.DB $20,$20,$B1,$B8
.DB $20,$20,$B1,$B9
.DB $20,$20,$B2,$B0
.DB $20,$20,$B2,$B1
.DB $20,$20,$B2,$B2
.DB $20,$20,$B2,$B3
.DB $20,$20,$B2,$B4
.DB $20,$20,$B2,$B5
.DB $20,$20,$B2,$B6
.DB $20,$20,$B2,$B7
.DB $20,$20,$B2,$B8
.DB $20,$20,$B2,$B9
.DB $20,$20,$B3,$B0
.DB $20,$20,$B3,$B1
.DB $20,$20,$B3,$B2
.DB $20,$20,$B3,$B3
.DB $20,$20,$B3,$B4
.DB $20,$20,$B3,$B5
.DB $20,$20,$B3,$B6
.DB $20,$20,$B3,$B7
.DB $20,$20,$B3,$B8
.DB $20,$20,$B3,$B9
.DB $20,$20,$B4,$B0
.DB $20,$20,$B4,$B1
.DB $20,$20,$B4,$B2
.DB $20,$20,$B4,$B3
.DB $20,$20,$B4,$B4
.DB $20,$20,$B4,$B5
.DB $20,$20,$B4,$B6
.DB $20,$20,$B4,$B7
.DB $20,$20,$B4,$B8
.DB $20,$20,$B4,$B9
.DB $20,$20,$B5,$B0
.DB $20,$20,$B5,$B1
.DB $20,$20,$B5,$B2
.DB $20,$20,$B5,$B3
.DB $20,$20,$B5,$B4
.DB $20,$20,$B5,$B5
.DB $20,$20,$B5,$B6
.DB $20,$20,$B5,$B7
.DB $20,$20,$B5,$B8
.DB $20,$20,$B5,$B9
.DB $20,$20,$B6,$B0
.DB $20,$20,$B6,$B1
.DB $20,$20,$B6,$B2
.DB $20,$20,$B6,$B3
.DB $20,$20,$B6,$B4
.DB $20,$20,$B6,$B5
.DB $20,$20,$B6,$B6
.DB $20,$20,$B6,$B7
.DB $20,$20,$B6,$B8
.DB $20,$20,$B6,$B9
.DB $20,$20,$B7,$B0
.DB $20,$20,$B7,$B1
.DB $20,$20,$B7,$B2
.DB $20,$20,$B7,$B3
.DB $20,$20,$B7,$B4
.DB $20,$20,$B7,$B5
.DB $20,$20,$B7,$B6
.DB $20,$20,$B7,$B7
.DB $20,$20,$B7,$B8
.DB $20,$20,$B7,$B9
.DB $20,$20,$B8,$B0
.DB $20,$20,$B8,$B1
.DB $20,$20,$B8,$B2
.DB $20,$20,$B8,$B3
.DB $20,$20,$B8,$B4
.DB $20,$20,$B8,$B5
.DB $20,$20,$B8,$B6
.DB $20,$20,$B8,$B7
.DB $20,$20,$B8,$B8
.DB $20,$20,$B8,$B9
.DB $20,$20,$B9,$B0
.DB $20,$20,$B9,$B1
.DB $20,$20,$B9,$B2
.DB $20,$20,$B9,$B3
.DB $20,$20,$B9,$B4
.DB $20,$20,$B9,$B5
.DB $20,$20,$B9,$B6
.DB $20,$20,$B9,$B7
.DB $20,$20,$B9,$B8
.DB $20,$20,$B9,$B9
.DB $20,$B1,$B0,$B0
.DB $20,$B1,$B0,$B1
.DB $20,$B1,$B0,$B2
.DB $20,$B1,$B0,$B3
.DB $20,$B1,$B0,$B4
.DB $20,$B1,$B0,$B5
.DB $20,$B1,$B0,$B6
.DB $20,$B1,$B0,$B7
.DB $20,$B1,$B0,$B8
.DB $20,$B1,$B0,$B9
.DB $20,$B1,$B1,$B0
.DB $20,$B1,$B1,$B1
.DB $20,$B1,$B1,$B2
.DB $20,$B1,$B1,$B3
.DB $20,$B1,$B1,$B4
.DB $20,$B1,$B1,$B5
.DB $20,$B1,$B1,$B6
.DB $20,$B1,$B1,$B7
.DB $20,$B1,$B1,$B8
.DB $20,$B1,$B1,$B9
.DB $20,$B1,$B2,$B0
.DB $20,$B1,$B2,$B1
.DB $20,$B1,$B2,$B2
.DB $20,$B1,$B2,$B3
.DB $20,$B1,$B2,$B4
.DB $20,$B1,$B2,$B5
.DB $20,$B1,$B2,$B6
.DB $20,$B1,$B2,$B7
.DB $20,$B1,$B2,$B8
.DB $20,$B1,$B2,$B9
.DB $20,$B1,$B3,$B0
.DB $20,$B1,$B3,$B1
.DB $20,$B1,$B3,$B2
.DB $20,$B1,$B3,$B3
.DB $20,$B1,$B3,$B4
.DB $20,$B1,$B3,$B5
.DB $20,$B1,$B3,$B6
.DB $20,$B1,$B3,$B7
.DB $20,$B1,$B3,$B8
.DB $20,$B1,$B3,$B9
.DB $20,$B1,$B4,$B0
.DB $20,$B1,$B4,$B1
.DB $20,$B1,$B4,$B2
.DB $20,$B1,$B4,$B3
.DB $20,$B1,$B4,$B4
.DB $20,$B1,$B4,$B5
.DB $20,$B1,$B4,$B6
.DB $20,$B1,$B4,$B7
.DB $20,$B1,$B4,$B8
.DB $20,$B1,$B4,$B9
.DB $20,$B1,$B5,$B0
.DB $20,$B1,$B5,$B1
.DB $20,$B1,$B5,$B2
.DB $20,$B1,$B5,$B3
.DB $20,$B1,$B5,$B4
.DB $20,$B1,$B5,$B5
.DB $20,$B1,$B5,$B6
.DB $20,$B1,$B5,$B7
.DB $20,$B1,$B5,$B8
.DB $20,$B1,$B5,$B9
.DB $20,$B1,$B6,$B0
.DB $20,$B1,$B6,$B1
.DB $20,$B1,$B6,$B2
.DB $20,$B1,$B6,$B3
.DB $20,$B1,$B6,$B4
.DB $20,$B1,$B6,$B5
.DB $20,$B1,$B6,$B6
.DB $20,$B1,$B6,$B7
.DB $20,$B1,$B6,$B8
.DB $20,$B1,$B6,$B9
.DB $20,$B1,$B7,$B0
.DB $20,$B1,$B7,$B1
.DB $20,$B1,$B7,$B2
.DB $20,$B1,$B7,$B3
.DB $20,$B1,$B7,$B4
.DB $20,$B1,$B7,$B5
.DB $20,$B1,$B7,$B6
.DB $20,$B1,$B7,$B7
.DB $20,$B1,$B7,$B8
.DB $20,$B1,$B7,$B9
.DB $20,$B1,$B8,$B0
.DB $20,$B1,$B8,$B1
.DB $20,$B1,$B8,$B2
.DB $20,$B1,$B8,$B3
.DB $20,$B1,$B8,$B4
.DB $20,$B1,$B8,$B5
.DB $20,$B1,$B8,$B6
.DB $20,$B1,$B8,$B7
.DB $20,$B1,$B8,$B8
.DB $20,$B1,$B8,$B9
.DB $20,$B1,$B9,$B0
.DB $20,$B1,$B9,$B1
.DB $20,$B1,$B9,$B2
.DB $20,$B1,$B9,$B3
.DB $20,$B1,$B9,$B4
.DB $20,$B1,$B9,$B5
.DB $20,$B1,$B9,$B6
.DB $20,$B1,$B9,$B7
.DB $20,$B1,$B9,$B8
.DB $20,$B1,$B9,$B9
.DB $20,$B2,$B0,$B0
.DB $20,$B2,$B0,$B1
.DB $20,$B2,$B0,$B2
.DB $20,$B2,$B0,$B3
.DB $20,$B2,$B0,$B4
.DB $20,$B2,$B0,$B5
.DB $20,$B2,$B0,$B6
.DB $20,$B2,$B0,$B7
.DB $20,$B2,$B0,$B8
.DB $20,$B2,$B0,$B9
.DB $20,$B2,$B1,$B0
.DB $20,$B2,$B1,$B1
.DB $20,$B2,$B1,$B2
.DB $20,$B2,$B1,$B3
.DB $20,$B2,$B1,$B4
.DB $20,$B2,$B1,$B5
.DB $20,$B2,$B1,$B6
.DB $20,$B2,$B1,$B7
.DB $20,$B2,$B1,$B8
.DB $20,$B2,$B1,$B9
.DB $20,$B2,$B2,$B0
.DB $20,$B2,$B2,$B1
.DB $20,$B2,$B2,$B2
.DB $20,$B2,$B2,$B3
.DB $20,$B2,$B2,$B4
.DB $20,$B2,$B2,$B5
.DB $20,$B2,$B2,$B6
.DB $20,$B2,$B2,$B7
.DB $20,$B2,$B2,$B8
.DB $20,$B2,$B2,$B9
.DB $20,$B2,$B3,$B0
.DB $20,$B2,$B3,$B1
.DB $20,$B2,$B3,$B2
.DB $20,$B2,$B3,$B3
.DB $20,$B2,$B3,$B4
.DB $20,$B2,$B3,$B5
.DB $20,$B2,$B3,$B6
.DB $20,$B2,$B3,$B7
.DB $20,$B2,$B3,$B8
.DB $20,$B2,$B3,$B9
.DB $20,$B2,$B4,$B0
.DB $20,$B2,$B4,$B1
.DB $20,$B2,$B4,$B2
.DB $20,$B2,$B4,$B3
.DB $20,$B2,$B4,$B4
.DB $20,$B2,$B4,$B5
.DB $20,$B2,$B4,$B6
.DB $20,$B2,$B4,$B7
.DB $20,$B2,$B4,$B8
.DB $20,$B2,$B4,$B9
.DB $20,$B2,$B5,$B0
.DB $20,$B2,$B5,$B1
.DB $20,$B2,$B5,$B2
.DB $20,$B2,$B5,$B3
.DB $20,$B2,$B5,$B4
.DB $20,$B2,$B5,$B5
; .DB $20,$10,$10,$10 ;^^^
.EXIT- Starichok51
- Модератор
- Сообщения: 19049
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Преобразование байта в три десятичные цифры
я вообще не могу представить ситуацию, когда требуется очень быстро преобразовать 1 байт.
а еще угробить 1 Кб программной памяти при этом...
к тому же, обычно приходится преобразовывать двухбайтовые числа.
а один байт - это такая большая редкость, что за нее бороться нет никакого смысла.
а еще угробить 1 Кб программной памяти при этом...
к тому же, обычно приходится преобразовывать двухбайтовые числа.
а один байт - это такая большая редкость, что за нее бороться нет никакого смысла.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Преобразование байта в три десятичные цифры
Малоубедительно. В теме более половины постов по быстрому преобразованию. У тебя просто не было таких задач. Удачи.
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Преобразование байта в три десятичные цифры
Обычно, если где-то нужно сделать много и быстро, я смотрю, а нельзя ли это много сделать заранее, обычно оказывается можно...
Те-же цифры: готовить следующий разряд не когда его уже зажигать пора, а как только завершились операции по зажиганию предыдущего, а как придет момент - просто взять готовый результат из буфера и применить.
Те-же цифры: готовить следующий разряд не когда его уже зажигать пора, а как только завершились операции по зажиганию предыдущего, а как придет момент - просто взять готовый результат из буфера и применить.
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Преобразование байта в три десятичные цифры
[uquote="akl",url="/forum/viewtopic.php?p=3660197#p3660197"]Малоубедительно.[/uquote]
Малоубедительно. Обычно преобразование чисел требуется для вывода на дисплей. Ну, передать по интерфейсу.
Я не вижу ни одной задачи, ради которой нужно создавать огромную таблицу с целью сэкономить несколько тактов.
Малоубедительно. Обычно преобразование чисел требуется для вывода на дисплей. Ну, передать по интерфейсу.
Я не вижу ни одной задачи, ради которой нужно создавать огромную таблицу с целью сэкономить несколько тактов.
- Starichok51
- Модератор
- Сообщения: 19049
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Преобразование байта в три десятичные цифры
а у тебя было?akl писал(а): У тебя просто не было таких задач.
да нет таких задач, где бы "лишние" 100, или даже 500, тактов создали цейтнот в вычислениях.
это самая натуральная развлекуха, не имеющая практического смысла.akl писал(а):В теме более половины постов по быстрому преобразованию.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Преобразование байта в три десятичные цифры
Собрался духом и реализовал и отладил код деления с остатком на 10 методом сдвигов и сложений для 16-ти и 24-битных величин.
Довольно таки объёмный код получился.
Добавлено after 5 minutes 39 seconds:
[uquote="Starichok51",url="/forum/viewtopic.php?p=3656425#p3656425"]
я вывожу на экран 3 раза в секунду, вместе с обработкой кнопок или энкодера, чтобы сразу видеть результат действия кнопок и энкодера. чаще выводить вообще нет никакого смысла.[/uquote]
Я фанат динамической индикации на семисегментниках, так как этот подход требует значительно меньше соединений и экономит буферные детали. А при динамической индикации "Бегущий огонёк" должен проскакивать по всем индикаторам как можно быстрее, чтобы создать иллюзию равномерного свечения. 25-50 раз в секунду — это в самый раз.
Спойлер
Код: Выделить всё
;==============
.def val1 = r16
.def val2 = r17
.def tmp1 = r18
.def tmp2 = r19
.def rem = r20
;==============
; Процедура осуществляет деление 16-битной величины на 10 с остатком
; методом сдвигов и сложений
; Размер: 80 байт
; Время: 40 тактов
; Регистры: 5 штук
ldi val1, 0x5F ; Исходная величина
ldi val2, 0xEA
mov rem, val1 ; Подготовка к вычислению остатка
; Расчёт целой части произведения делимого на величину 0.8 (10) =
; = 0.1100 1100 1100 1100... (2)
lsr val2 ; x 0.1 (2)
ror val1
mov tmp1, val1 ; x 1.1 (2)
mov tmp2, val2
lsr tmp2
ror tmp1
add val1, tmp1
adc val2, tmp2
mov tmp1, val1 ; x 1.0001 (2)
swap tmp1
andi tmp1, 0x0F
mov tmp2, val2
swap tmp2
eor tmp1, tmp2
andi tmp2, 0x0F
eor tmp1, tmp2
add val1, tmp1
adc val2, tmp2
ldi tmp1, 0x01 ; Инициализация вспомогательных 0 и 1
ldi tmp2, 0x00
add val1, val2 ; x 1.0000 0001 (2)
adc val2, tmp2
; Умножение сдвигами и сложением закончилось
add val1, tmp1 ; Коррекция рассчитанного произведения.
adc val2, tmp2
sbrc val2, 7
add val1, tmp1
sbrc val2, 7
adc val2, tmp2
andi val1, 0xF8 ; Искомое частное, умноженное на 8
sub rem, val1 ; Вычисление искомого остатка (вычитание)
lsr val2 ; одновременно с искомым частным
ror val1 ; (деление на 8)
lsr val2
ror val1
sub rem, val1
lsr val2
ror val1
; Конец процедуры
;==============
Спойлер
Код: Выделить всё
;==============
.def val1 = r16
.def val2 = r17
.def val3 = r18
.def tmp1 = r19
.def tmp2 = r20
.def tmp3 = r21
.def rem = r22
;==============
; Процедура осуществляет деление 24-битной величины на 10 с остатком
; методом сдвигов и сложений
; Размер: 122 байта
; Время: 61 такт
; Регистры: 7 штук
ldi val1, 0x7F ; Исходная величина
ldi val2, 0x96
ldi val3, 0x98
mov rem, val1 ; Подготовка к вычислению остатка
; Расчёт целой части произведения делимого на величину 0.8 (10) =
; = 0.1100 1100 1100 1100 1100 1100... (2)
lsr val3 ; x 0.1 (2)
ror val2
ror val1
mov tmp1, val1 ; x 1.1 (2)
mov tmp2, val2
mov tmp3, val3
lsr tmp3
ror tmp2
ror tmp1
add val1, tmp1
adc val2, tmp2
adc val3, tmp3
mov tmp1, val1 ; x 1.0001 (2)
swap tmp1
andi tmp1, 0x0F
mov tmp2, val2
swap tmp2
eor tmp1, tmp2
andi tmp2, 0x0F
eor tmp1, tmp2
mov tmp3, val3
swap tmp3
eor tmp2, tmp3
andi tmp3, 0x0F
eor tmp2, tmp3
add val1, tmp1
adc val2, tmp2
adc val3, tmp3
ldi tmp1, 0x01 ; Инициализация вспомогательных 0 и 1
ldi tmp2, 0x00
add val1, val2 ; x 1.0000 0001 (2)
adc val2, val3
adc val3, tmp2
add val1, val3 ; x 1.0000 0000 0000 0001 (2)
adc val2, tmp2
adc val3, tmp2
; Умножение сдвигами и сложением закончилось
add val1, tmp1 ; Коррекция рассчитанного произведения.
adc val2, tmp2
adc val3, tmp2
sbrc val3, 7
add val1, tmp1
sbrc val3, 7
adc val2, tmp2
sbrc val3, 7
adc val3, tmp2
andi val1, 0xF8 ; Искомое частное, умноженное на 8
sub rem, val1 ; Вычисление искомого остатка (вычитание)
lsr val3 ; одновременно с искомым частным
ror val2 ; (деление на 8)
ror val1
lsr val3
ror val2
ror val1
sub rem, val1
lsr val3
ror val2
ror val1
; Конец процедуры
;==============Добавлено after 5 minutes 39 seconds:
[uquote="Starichok51",url="/forum/viewtopic.php?p=3656425#p3656425"]
а зачем так часто?B@R5uk писал(а):Так что к процедуре, которая вызывается раз в 20-40 мс, нет смысла предъявлять жёсткие требования по быстродействию.
я вывожу на экран 3 раза в секунду, вместе с обработкой кнопок или энкодера, чтобы сразу видеть результат действия кнопок и энкодера. чаще выводить вообще нет никакого смысла.[/uquote]
Я фанат динамической индикации на семисегментниках, так как этот подход требует значительно меньше соединений и экономит буферные детали. А при динамической индикации "Бегущий огонёк" должен проскакивать по всем индикаторам как можно быстрее, чтобы создать иллюзию равномерного свечения. 25-50 раз в секунду — это в самый раз.
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Преобразование байта в три десятичные цифры
25- очень мало, 50 - только для неподвижного экрана, когда мне понадобились часы в машину, частоты ниже 500гц (на весь дисплей) были отметены сразу, иначе даже при небольшой тряске видно только набор сегментов...
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Преобразование байта в три десятичные цифры
Только сканирование матрицы вообще никак не связано с подготовкой данных для индикаторов! Или вы для каждого индикатора на лету вычисляет сегменты?! Это же кошмар не рождённого!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Преобразование байта в три десятичные цифры
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3663807#p3663807"]25- очень мало, 50 - только для неподвижного экрана, когда мне понадобились часы в машину, частоты ниже 500гц (на весь дисплей) были отметены сразу, иначе даже при небольшой тряске видно только набор сегментов...[/uquote]
Динамическую индикацию делал для частотомера, для счётчика витков и просто для экспериментального цифрового индикатора на АЛС318. Всё это стационарные устройства, так что небольшой частоты хватало. Возьму ваш опыт на заметку, если вдруг какие мобильные индикаторы буду делать. Спасибо.
ARV, у частотомера цикл измерения около секунды, на 16 МГц это как раз 24 значащих бит частоты. Так что раз в секунду и рассчитывал. Хотя можно придумать какой-нибудь скоростной режим с пониженной точностью и повышенной скоростью индикации. Чисто для разнообразия.
Динамическую индикацию делал для частотомера, для счётчика витков и просто для экспериментального цифрового индикатора на АЛС318. Всё это стационарные устройства, так что небольшой частоты хватало. Возьму ваш опыт на заметку, если вдруг какие мобильные индикаторы буду делать. Спасибо.
ARV, у частотомера цикл измерения около секунды, на 16 МГц это как раз 24 значащих бит частоты. Так что раз в секунду и рассчитывал. Хотя можно придумать какой-нибудь скоростной режим с пониженной точностью и повышенной скоростью индикации. Чисто для разнообразия.
Re: Преобразование байта в три десятичные цифры
[uquote="Ser60",url="/forum/viewtopic.php?p=3658216#p3658216"]...Приводимый ниже рекордно быстрый алгоритм годится только для архитектуры MSP430X. В ней имеется таймер реального времени RTC_B, в состав которого входит регистр BIN2BCD...[/uquote]Моё любимое семейство. Ниже приведен классический код преобразования в BCD с использованием команды сложения с десятичной коррекцией. Вы наверняка его знаете, но мало ли кому пригодится для этого семейства без встроенного регистра BIN2BCD. Он не такой шустрый, зато работает в диапазоне 0...65535. Очень легко наращивается для преобразования больших чисел. Жаль что AVR не имеет аналогичной команды.
Спойлер
Код: Выделить всё
BIN_BCD:
;R9-BIN R13,R14-BCD формат старший-младший
MOV #16,R15
CLR R13
CLR R14
BIN_BCD1:
RLA R9
DADD R14,R14
DADD R13,R13
DEC R15
JNZ BIN_BCD1
;конец преобразования 100 циклов
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Преобразование байта в три десятичные цифры
и для этого вам потребовалось достигать минимума тактов на преобразование?! Даже самый тупейший метод (кажется больше 700 тактов - поправьте, если ошибся) при тактовой частоте "всего" в 1 МГц за 1 секунду позволит преобразовать в символы 1428 байтов!B@R5uk писал(а):Так что раз в секунду и рассчитывал.
как было сказано, данная тема имеет чисто спортивный смысл, никакой практической пользы она не содержит.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Преобразование байта в три десятичные цифры
2 AVR:[uquote="B@R5uk",url="/forum/viewtopic.php?p=3656442#p3656442"]...просто спортивный и академический интерес...[/uquote]
Добавлено after 27 minutes 48 seconds:
Между тем, я тут подумал и понял: поскольку вычитание единицы из трёхбайтной величины довольно накладная операция на 8-битном МК, то в процедуре деления на 10 сдвигами и сложением этой 24-битной величины лучше коррекцию делать как было предложение в оригинальной статье: вычитанием в конце из остатка 10, если он больше 10, и увеличением частного на 1. Экономия в 3 такта:
Добавлено after 27 minutes 48 seconds:
Между тем, я тут подумал и понял: поскольку вычитание единицы из трёхбайтной величины довольно накладная операция на 8-битном МК, то в процедуре деления на 10 сдвигами и сложением этой 24-битной величины лучше коррекцию делать как было предложение в оригинальной статье: вычитанием в конце из остатка 10, если он больше 10, и увеличением частного на 1. Экономия в 3 такта:
Спойлер
Код: Выделить всё
;==============
.def val1 = r16
.def val2 = r17
.def val3 = r18
.def tmp1 = r19
.def tmp2 = r20
.def tmp3 = r21
.def rem = r22
;==============
; Процедура осуществляет деление 24-битной величины на 10 с остатком
; методом сдвигов и сложений
; Размер: 120 байт
; Время: 58 тактов
; Регистры: 7 штук
ldi val1, 0x75 ; Исходная величина
ldi val2, 0x96
ldi val3, 0x98
mov rem, val1 ; Подготовка к вычислению остатка
; Расчёт целой части произведения делимого на величину 0.8 (10) =
; = 0.1100 1100 1100 1100 1100 1100... (2)
lsr val3 ; x 0.1 (2)
ror val2
ror val1
mov tmp1, val1 ; x 1.1 (2)
mov tmp2, val2
mov tmp3, val3
lsr tmp3
ror tmp2
ror tmp1
add val1, tmp1
adc val2, tmp2
adc val3, tmp3
mov tmp1, val1 ; x 1.0001 (2)
swap tmp1
andi tmp1, 0x0F
mov tmp2, val2
swap tmp2
eor tmp1, tmp2
andi tmp2, 0x0F
eor tmp1, tmp2
mov tmp3, val3
swap tmp3
eor tmp2, tmp3
andi tmp3, 0x0F
eor tmp2, tmp3
add val1, tmp1
adc val2, tmp2
adc val3, tmp3
ldi tmp1, 0x01 ; Инициализация вспомогательных 0 и 1
ldi tmp2, 0x00
add val1, val2 ; x 1.0000 0001 (2)
adc val2, val3
adc val3, tmp2
add val1, val3 ; x 1.0000 0000 0000 0001 (2)
adc val2, tmp2
adc val3, tmp2
; Умножение сдвигами и сложением закончилось
andi val1, 0xF8 ; Искомое частное, умноженное на 8
sub rem, val1 ; Вычисление искомого остатка (вычитание)
lsr val3 ; одновременно с искомым частным
ror val2 ; (деление на 8)
ror val1
lsr val3
ror val2
ror val1
sub rem, val1
lsr val3
ror val2
ror val1
; Коррекция результатов расчёта
subi rem, 0x0A ; Если остаток больше или равен 10, то
brcc PC+4
subi rem, 0xF6
nop
rjmp PC+4
add val1, tmp1 ; уменьшить остаток на 10 и
adc val2, tmp2 ; увеличить частное на 1
adc val3, tmp2
; Конец процедуры
;==============

