Цитата(Abell @ Dec 19 2006, 16:43)

Подскажите, плз, какие алгоритмы вообще существуют для разделения числа на разряды? есть задача, требуется отобразить измеренное значение на семисегментном динамическом дисплее. создал массив по количеству разрядов, в цикле делю исходное число на 10 без остатка, обратно умножаю на 10 и вычитаю из исходного. так все получается, но, может, есть более простые/быстрые пути?
Деление на 10 довольно неэффективно на МК, где нет аппаратной операции деления. Намного эффективнее работает схема на основе представления числа в виде полинома Горнера. Цитата из эхо-конференции ru.embedded (эх, хорошие были времена

):
Цитата
Алгоритм менее простой:десятичный эквивалент числа Х можно получить, сдвигая
двоичное число влево и подавая выдвигаемые двоичные цифры в младший разряд
десятичного регистра. Одновременно со сдвигом двоичного регистра необходимо
удваивать содержимое десятичного регистра. Метод основан на представлении числа
в виде полинома Горнера:
Х=Xn-1*2^(n-1)+Xn-2*2^(n-2)+...+X1*2+X0 - это дв.представление
X=(...(Xn-1*2+Xn-2)*2+...+X1)*2+X0 - это по Горнеру
Абисняю на примере. Имеем дв.код 1111 , т.е. 15
1) выдвигаем влево 1-ю ед. из дв.рг
2) удваиваем сод. дес.рг (0*2=0000_0000)
не забываем, что удвоение - десятичное, т.е. с коррекцией
3) вдвигаем выдв.1 в дес.рг(0000_0001)
4) шаг 1
5) шаг 2 (1*2=0000_0010)
6) шаг 3 (0000_0011)
7) шаг 1
8) шаг 2 (3*2=0000_0110)
9) шаг 3 (0000_0111)
10) шаг 1
11) шаг 2 Внимание! Самое интересное:
в данном случае удвоение происходит так:
т.к. исх.число >= 5 , то вводим коррекцию +3
получаем 0000_1010, удваиваем ЭТО число (0001_0100)
12)шаг 3 (0001_0101) Это что? Вроде бы дв/дес. 15. Hе так ли ?
Я на основе этого алгоритма когда-то слепил для себя подпрограмму для MSP430:
Код
bin2BCD16:
; r11 - bit counter
; r12 - input binary number
; r13 - result (low: 4 digits)
; r14 - addr
; r15 - result (high: 1 digit)
mov.w #16,r11
clr r13
clr r15
;-----------------------------------
convert:
clr r10
rla r12
rlc r10
dadd.w r13,r13
dadd.w r15,r15
dadd.w r10,r13
dadd.w #0,r15
dec r11
jne convert
Это, собственно, код преобразования. Результат получается упаковынный по тетрадам (ниблам). У меня там дальше еще шел код распаковки каждой цифири в отдельный байт, но это к делу уже не относится.
Для AVR есть аналогичная подпрограмма, правда, я ее не писал сам, она идет в какой-то атмеловской аппликухе. Я ее лишь адаптировал для возможности вызова в IAR (под соглашения о вызове подрихтовал). На AVR выходит не так коротко, т.к. он, во-первых, 8-разрядный (а тут 16 бит актуальны), во-вторых, у AVR нет инструкций десятичной коррекции при сложении, а у MSP430 есть. Но принцип везде один и тот же, помедитируйте, разобраться не так сложно.