Главная страница


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)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 алгоpитмы пеpевода двоичного числа в двоично-десятичное   Dmitry Oboukhov   17 Jan 2002 22:21:19 
 Re: алгоpитмы пеpевода двоичного числа в двоично-десятичное   Sergey Kovalev   18 Jan 2002 14:32:56 
 алгоpитмы пеpевода двоичного числа в двоично-десятичное   Dmitry Oboukhov   18 Jan 2002 19:14:14 
 Re: алгоpитмы пеpевода двоичного числа в двоично-десятичное   Pavel Fomin   18 Jan 2002 23:27:18 
 алгоpитмы пеpевода двоичного числа в двоично-десятичное   Alex Astafiev   21 Jan 2002 11:43:28 
Архивное /ru.algorithms/160653c48a5e0.html, оценка 1 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional