|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Pavel Fomin 2:5026/49.21 18 Jan 2002 23:27:18 To : Dmitry Oboukhov Subject : Re: алгоpитмы пеpевода двоичного числа в двоично-десятичное -------------------------------------------------------------------------------- 17 Jan 02 21:21, you wrote to All: DO> сабж В свое время мне один человек присылал исходник для PIC16F84 с просьбой разобраться. Здесь я приведу оригинальный исходник, а ниже комментарии по алгоритму. DO> замечания: DO> очень мало места Посмотри, может уложишься. Алгоритм быстрый и скорость практически не зависит от значения числа. DO> дополнительных. МК не умеет умножать и вычитать, тока складывает байты, сдвиги он тоже наверняка понимает. === Cut === OD>> PS: Пишется прога для микроконтроллера. PF> Упс. Так под какой? PIC16F84. Если шаришь то бросаю исходник. Извини за съехавшю табуляцию. Прога работает но застрелите не понимаю как :-) === Cut === ;-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-- ;"bin4BCD32" ; Подпрограмма преобразования ; 32-разрядного двоичного числа (HEX) ; в двоично-десятичное число (BCD). ; Выполняется для всех чисел за 2554 тактов прмерно :-) ; ;Используемые регистры (11 шт.): ; BitCnt, DataL, DataH, DataH1, DataH2 ; BCDL, BCDH, BCDH1, BCDH2, BCDH3 ; TEMP, регистр косвенной адресации FSR. ; ; | DataH2| DataH1| DataH | DataL | ; |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|-HEX maxim (FF FF FF FF) ; ; | BCDH3 | BCDH2 | BCDH1 | BCDH | BCDL | ; |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|-BCD max 4 294 967 295 ; ; В И М А И Е ! ; После выполнения подпрограммы ; регистры DataH2,DataH1,DataH и DataL обнуляются. ; LIST P=16C84 org 0 f equ 1 w equ 0 carry equ 0 ;бит переноса carry в регистре status zero equ 2 ;бит нолевого результата в регистре status status equ h'03' ;регистр статуса FSR equ h'0004' INDF equ h'0000' BitCnt equ h'000d' ;счетчик сдвинутых бит (в этом случае = 32 DEC) DataL equ h'000e' ;разряды 32 битного счетчика (млабший байт) DataH equ h'000f' ; DataH1 equ h'0010' ; DataH2 equ h'0011' ;разряды 32 битного счетчика (старший байт) BCDL equ h'0012' ;10-тичное конечное число (младший разряд) BCDH equ h'0013' ;у нас DEC макс. 4294967295 -> 10 разрядов 5 байт BCDH1 equ h'0014' ;4 бита на десятичный разряд BCDH2 equ h'0015' ; BCDH3 equ h'0016' ;10-тичное конечное число (старший разряд) TEMP equ h'0017' ;хрен знает что это похоже просто темповая переменная start nop ;забиваем все исходные данные ff ff ff ff movlw h'ff' movwF DataL movwF DataH movwF DataH1 movwF DataH2 ;отваливаем на конвертацию HEX -> DEC call bin4BCD32 ;далее просто зацикливаем программу что дальше не лезла :-) st01 goto st01 bin4BCD32 movlw .32 movwf BitCnt ;загрузка счетчика бит числом 32. clrf BCDH3 ;очистка регистров хранения результатов. clrf BCDH2 clrf BCDH1 clrf BCDH clrf BCDL bBCDx_1 bcf status,carry ;очистка флага-переноса Carry. rlf DataL,F ;сдвиг входных данных rlf DataH,F ;через все байты. rlf DataH1,F ; rlf DataH2,F ; rlf BCDL,F ;сдвиг итоговых данных rlf BCDH,F ;через все байты. rlf BCDH1,F ; rlf BCDH2,F ; rlf BCDH3,F ; decfsz BitCnt, F ;уменьшение счетчика бит на единицу. goto bBCDx_2 ;при обнулении счетчика return ; выход из подпрограммы. ; с этого момента полный _п****ц_ ; я уже не прослеживаю логику но тем не менее ; все работает и конвертит так как надо bBCDx_2 ;иначе --> продолжение. movlw BCDH3+1 ;загрузить регистр косвенной адресации movwf FSR ;адресом на единицу больше bBCDx_3 ;адреса старшей цифры BCD числа. decf FSR, F ;адрес уменьшить на единицу. movf INDF, W ;загрузить в аккумулятор значение ;косвенно-адресуемого регистра, addlw 3 ;прибавить 0x03, movwf TEMP ;результат поместить в дополнительный регистр. btfsc TEMP, 3 ;если бит 3 установлен (== 1) movwf INDF ;результат поместить обратно ;в регистр-источник. movf INDF, W ;загрузить в аккумулятор значение ;косвенно-адресуемого регистра, addlw 30 ;прибавить 0x30, movwf TEMP ;результат поместить в дополнительный регистр. btfsc TEMP, 7 ;если старший бит установлен (== 1) movwf INDF ;результат поместить обратно ;в регистр-источник. movlw BCDL ;проверка равенства косвенного адреса subwf FSR, W ;адресу младшей цифры BCD числа. ;если не равен, повторить операцию для ;всех цифр. btfss status,zero goto bBCDx_3 goto bBCDx_1 ;повторить операцию для всех бит. end === Cut === === Cut === === Cut === Суть такова, что допустим начальное число N мы делили на 2 нацело 31 раз и получили 32 числа: N, [N/2], [[N/2]/2],... Теперь на каждом шаге в результате будет содержаться соответствующий результат. Фактически у нас на каждом шаге имеется корректное BCD число, и его надо умножить на 2 (при необходимости +1). Осталось понять фокус с умножением... 1)делаем битовый сдвиг 32-bit числа влево 2)делаем битовый сдвиг BCD числа влево (*2), чтобы в результате сдвига получилось BCD-число, предварительно его надо скорректировать. Hо в первый раз у нас там 0 - можно и не корректировать. Цифры 0..4 умножаться нормально, а 5..9 надо корректировать. 3) иначе производим коррекцию (31 раз как я понял - 31..1) Коррекция похоже производится таким образом, что после следующего умножения число снова становится BCD. 4) цикл по байтам - возможен в любом порядке. 5) берем очередной байт. 6) обрабатываем младшую цифру - 4 бита для чисел 5..9 получаем 8..12 (1000..1100)(после умножения *2 будет перенос в следующий знак, т.е. для него будет не схема *2, а *2+1) (5 после *2 станет 0, 6 станет 2, 7 - 4, 8 - 6, 9 - 8, десяток перейдет дальше) 7) Тот самый случай - числа 5..9 корректируются для последующего умножения. NB: После умножения каждое число становится четным, т.е. максимум 8, т.е. после +1 не происходит нарушения BCD-числа. 8) теперь повторяем все для второго знака (старшие 4 бита). и так далее для каждого байта === Cut === Если не понятно, прокомментирую подробнее. Pasha 1st, RU.(PASCAL[.SOURCES|.CHAINIK|.ASM]|ACM) ... Говорила мне мама: "Hе лезь в системщики" --- GoldED/W32 3.0.1-asa9 SR3 * Origin: Windows имеет всех, кто ее имеет (2:5026/49.21) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/160653c48a5e0.html, оценка из 5, голосов 10
|