搜索
bottom↓
回复: 24

89C51做的计算器(原作)

[复制链接]

出0入0汤圆

发表于 2011-7-8 01:56:48 | 显示全部楼层 |阅读模式
89C51计算器:   主要芯片:89C51、74HC244、ULN2003--2片、共阴数码管12只、集成电阻3块、24键盘一只


程序:


;*****************************  89C51计算器调试程序  **************************

;      主要芯片:89C51、74HC244、ULN2003--2片、共阴数码管12只、集成电阻3块、24键盘一只

;      试验电路图见笔记(小)   试验时间:2008/01/04    地点:北京清河宝盛北里

;      连接方式:1、数码管和单片机 a---HC244(11)---P1.7    b--HC244(13)--P1.6  ;

;                                c--HC244(15)--P1.5      d--HC244(17)--P1.4    ;

;                                e-HC244(8)--P1.3    f--HC244(6)--p1.2         ;

;                               g-HC244(4)--P1.1      dp---HC244(2)---p1.0     ;

;  |——|——|——|——|——|——|——|——|——|——|——|——|     |——A——|
;  |    |    |    |    |    |    |    |    |    |    |    |    |     |         |
;  |——|——|——|——|——|——|——|——|——|——|——|——|     F         B
;  |    |    |    |    |    |    |    |    |    |    |    |    |     |——G——|
;  |——|——|——|——|——|——|——|——|——|——|——|——|     |         |
;   P2.0  P2.1 P2.2 P2.3 P2.4 P2.5 P2.6 P2.7 P0.7 P0.6 P0.5 P0.4     E         C
;                                                                    |——D——| 。DP
;
;                 键盘和单片机                                        数码管
;

;               2、键盘各单片机:——|——|——|——|——|——|——|——|——P0.0
;                                ——|——|——|——|——|——|——|——|——P0.1
;                                ——|——|——|——|——|——|——|——|——P0.2
;                                   P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7
;**********************************************************************************************
       HUAN_ZHEN1  EQU   50H  ;按键值缓存单元首地址;最多13个:6位整数,六位小数。一个小数点;        
                              ; 或13位整数。50-5CH (占用)。

       HUAN_ZHEN2  EQU   40H  ;按键值缓存单元首地址;最多13个:6位整数,六位小数。一个小数点;
        
                              ; 或13位整数。40-4CH (占用)。

       HZ_JS1       EQU   5DH  ; 按键次数计数器---缓存个数

       HZ_JS2       EQU   4DH  ; 按键次数计数器---缓存个数
         
       X1AN_SHI_ADD EQU   20H  ;  显示存贮区首地址  
      
       DATA_CONT    EQU    5EH ;  输入操作数---次数计数
     
       ; 23H-------浮点子程序占用23H---数符---其它程序不能用此单元
      
       ; 25H-------单元供运算结果--阶码--存贮用 ,便于分析小数点位置

       ; 26H------阶码处理缓存单元

       ; 27H------运算符号处理缓存单元

       ; 28H----- 运算符号键值保存单元

       ; 29H----- 运算符号键值保存单元----按第1个操作数时

       ; 2AH----- 运算符号键值保存单元----按第2个操作数时
     

;****************************  主程序   *********************************

ORG    0000H    ;   开始地址

MAIN:   NOP     ; 小延时
        NOP     ;
        NOP     ;


;---------------------------------------------------------  
       MOV  R1,#7FH   ;  89C51内存储器00H-7FH 各单元清0-------2fh

        MOV R0,#00H    ;---------30h

        MOV A,#00H     ;

K1:     MOV @R0,A      ;

        INC R0         ;

        DJNZ R1,  K1   ;
;----------------------------------------------------------
        MOV SP,#60H         ;  设堆栈

        CLR  EA             ;  关总中断

        MOV P0,#00H         ;  关显示
        MOV P1,#00H         ;
        MOV P2,#00H         ;

        MOV P3,#0FFH        ;  P3为输入口
        
MAIN1:  LCALL  KEY1         ;  调用键盘处理程序
      
        mov 29h, 28h        ;  转移第 1 次按键的--符号值---

        LCALL   FD_FDBCD    ;  调用第一个操作数到四字节浮点BCD转换子程序
                            ;  结果在30H、31H、32H、33H中

       MOV  3CH,30H         ;  转移第一操作数结果
       MOV  3DH,31H         ;
       MOV  3EH,32H         ;
       MOV  3FH,33H         ;

    ;  AJMP  XX1            ; 在此可查看出按键和转换结果

       LCALL  DISPLAY_CLR   ;  显示单元50H-5BH 清0

       LCALL  KEY1          ;  调用键盘处理程序

       mov 2ah, 28h         ;  转移第 2 次按键的--符号值---

       LCALL   FD_FDBCD     ;  调用第二个操作数到四字节浮点BCD转换子程序

                            ;  结果在30H、31H、32H、33H中


       mov   a,29h          ;  取出第1次按键符号值

       cjne a,#0bh, k2      ;  是“+”?,不是转出
  
       ajmp  add_1          ;  是的转“+”运算处理程序

k2:    cjne a,#0ch, k3      ;  是“-”?,不是转出
  
       ajmp  sub_1          ;  是的转“-”运算处理程序

k3:    cjne a,#0dh, k4      ;  是“*”?,不是转出
  
       ajmp  mul_1          ; 是的转“*”运算处理程序

k4:    cjne a,#0eh, k5      ;  是“/”?,不是转出
  
       ajmp  div_1          ; 是的转“/”运算处理程序

k5:    cjne a,#0fh, k6      ;  是“ce”?,不是转出
  
       ajmp  ce_1           ;  是的转“ce”运算处理程序----清屏幕

k6:    ljmp   main1         ;  出错,从头开始


;---------------------  作加法运算    --------------------------

add_1: MOV R0,#3cH    ; 指向BCD 码浮点操作数 1 的首地址-----格式化数必须在R0中,结果也在R0中。

       LCALL BTOF     ; 将其转换成二进制浮点操作数

       MOV R0,#30H    ; 指向BCD 码浮点操作数 2 的首地址

       LCALL BTOF     ; 将其转换成二进制浮点操作数
      
       MOV R0,#3cH    ; 指向二进制浮点操作数1---被加数
   
       MOV R1,#30H    ; 指向二进制浮点操作数2---加数
   
       LCALL FADD     ; 进行浮点加法运算--- 1+2----------------

       LCALL FTOB     ; 将结果转换成BCD 码浮点数--结果在被加数中

       MOV  25H ,3cH  ;   阶码送保存,便于分析小数点位置

       ljmp   xx1     ;

;----------------------------------------------------------------   

;---------------------  作减法运算    --------------------------

sub_1: MOV R0,#3CH    ; 指向BCD 码浮点操作数 1 的首地址-----格式化数必须在R0中,结果也在R0中。

       LCALL BTOF     ; 将其转换成二进制浮点操作数

       MOV R0,#30H    ; 指向BCD 码浮点操作数 2 的首地址

       LCALL BTOF     ; 将其转换成二进制浮点操作数
      
       MOV R0,#3CH    ; 指向二进制浮点操作数1---被加数----------
   
       MOV R1,#30H    ; 指向二进制浮点操作数2---加数-----------
   
       LCALL FSUB     ; 进行浮点减法运算--- 1-2 ---

       LCALL FTOB     ; 将结果转换成BCD 码浮点数--结果在被加数中

       MOV  25H ,3CH  ;   阶码送保存,便于分析小数点位置

       ljmp   xx1     ;

;----------------------------------------------------------------   


;---------------------  作乘法运算    --------------------------

mul_1: MOV R0,#3CH    ; 指向BCD 码浮点操作数 1 的首地址-----格式化数必须在R0中,结果也在R0中。

       LCALL BTOF     ; 将其转换成二进制浮点操作数

       MOV R0,#30H    ; 指向BCD 码浮点操作数 2 的首地址

       LCALL BTOF     ; 将其转换成二进制浮点操作数
      
       MOV R0,#3CH    ; 指向二进制浮点操作数1---被加数
   
       MOV R1,#30H    ; 指向二进制浮点操作数2---加数
   
       LCALL FMUL     ; 进行浮点乘法运算--- 1*2-----------

       LCALL FTOB     ; 将结果转换成BCD 码浮点数--结果在被加数中

       MOV  25H ,3CH  ;   阶码送保存,便于分析小数点位置

       ljmp   xx1   ;

;----------------------------------------------------------------   


;---------------------  作除法运算    --------------------------

div_1: MOV R0,#3CH    ; 指向BCD 码浮点操作数 1 的首地址-----格式化数必须在R0中,结果也在R0中。

       LCALL BTOF     ; 将其转换成二进制浮点操作数

       MOV R0,#30H    ; 指向BCD 码浮点操作数 2 的首地址

       LCALL BTOF     ; 将其转换成二进制浮点操作数
      
       MOV R0,#3CH    ; 指向二进制浮点操作数1---被加数
   
       MOV R1,#30H    ; 指向二进制浮点操作数2---加数
   
       LCALL FDIV     ; 进行浮点加法运算--- 1/2 ----------

       LCALL FTOB     ; 将结果转换成BCD 码浮点数--结果在被加数中

       MOV  25H ,3CH  ;   阶码送保存,便于分析小数点位置

       ljmp   xx1     ;

;----------------------------------------------------------------   
ce_1:     LJMP   MAIN ;  从头开始
      
;----------------------------------------------------------------   

XX1:  MOV A  ,3CH    ;  结果送显示
       ANL A,#0F0H    ;
       SWAP A         ;
       MOV 50H,A      ;
       MOV A,3CH      ;
       ANL A,#0FH     ;
       MOV 51H,A      ;

       MOV A  ,3DH    ;  结果送显示
       ANL A,#0F0H    ;
       SWAP A         ;
       MOV 52H,A      ;
       MOV A,3DH      ;
       ANL A,#0FH     ;
       MOV 53H,A      ;

       MOV A  ,3EH    ;  结果送显示
       ANL A,#0F0H    ;
       SWAP A         ;
       MOV 54H,A      ;
       MOV A,3EH      ;
       ANL A,#0FH     ;
       MOV 55H,A      ;

       MOV A  ,3FH    ;  结果送显示
       ANL A,#0F0H    ;
       SWAP A         ;
       MOV 56H,A      ;
       MOV A,3FH      ;
       ANL A,#0FH     ;
       MOV 57H,A      ;

       MOV 58H,#00H   ; 显示“0”
       MOV 59H,#00H   ;
       MOV 5AH,#00H   ;
       MOV 5BH,#00H   ;

;---------------------------------------------------------------

XX2:   MOV 25H,3CH            ;  阶码保存

       XX4:  LCALL  XIAN_SHI  ;  调显示

       MOV A,P3               ;  读键盘口

        CJNE  A,#0FFH ,XX3    ; 比较是否有键按下,不相等有键按下转出。

        AJMP   XX4            ;  无键盘按下,继续显示            

XX3:  AJMP  MAIN1            ;  从头开始--------main1

;***********************    主程序结束    ******************************


;************************  键盘处理程序  ***************************

KEY1:   MOV HZ_JS2,#00H     ;计数初值
   
        MOV HZ_JS1,#00H     ;计数初值

        MOV 4FH,#50H        ;显示初值

;-----------------------------------

KEY:   MOV R1,#00H   ; 列值清零

        MOV 25H,#0FFH ;  区分是键盘显示还是运算结果显示----标致位

        SETB P0.1     ;
        SETB P0.2     ;
        CLR  P0.0     ;  扫描第一行

        MOV R3,#10H   ;  行初值

        MOV A,P3      ;   读入A中,看是否有键接下?

        MOV R4,A      ;  存入R4,以判断是否放开?

        SETB C        ;   置进位位
   
        MOV R5,#08    ;  共八列
           
L3:     RLC  A        ;  左环移一位

        JNC KEYIN     ;  C=0 时,有键接下,转键值处理程序

        INC R1        ;  C=1无键按下,列值加一

        DJNZ R5, L3   ;  列计数减一返回开始扫其它行
;---------------------------------
        SETB P0.0     ;
        SETB P0.2     ;
        CLR  P0.1     ; 扫描第二行

        MOV R3,#00H   ;   第二行初值

        MOV A,P3      ; 读入A中

        MOV R4,A      ;  保存 存入R4,以判断是否放开?

        SETB C        ;  置高

        MOV R1,#00H   ; 列值清零

        MOV R5,#08    ;   共八列
      
L31:    RLC  A        ;  左环移一位

        JNC KEYIN     ;  C=0J时,有键接下,转键值处理程序

        INC R1        ; C=1无键按下,列值加一

        DJNZ R5, L31  ;
;--------------------------------------
        SETB P0.0       ;
        SETB P0.1       ;
        CLR  P0.2       ;   扫描第三行
  
        MOV R3,#08H     ;   第三行行初值

        MOV A,P3        ;   读入A中

        MOV R4,A        ;   存入R4,以判断是否放开?

        SETB C          ;

        MOV R1,#00H     ;   列值清零

        MOV R5,#08      ;   共八列
           
L32:     RLC  A         ;   左环移一位
      
        JNC KEYIN       ;   C=0 时,有键接下,转键值处理程序

        INC R1          ;   C=1无键按下,列值加一

        DJNZ R5, L32    ;

        AJMP   D6       ;   无键按下直到显示子程序

;----------------------------------------------------

KEYIN:   LCALL  XIAN_SHI  ;调用显示来代替延时

D3:    MOV A,P3         ;  再读入P3的值
         
       XRL A,R4         ;  与上次读入的值作比较
  
       JZ  D3           ;  ACC=0  表示键未释放

       MOV  A,R1        ;  取出按键列值

       ADD A,R3         ;  和行值相加得到键值----A

       mov  27h,a       ;   暂存按键值

       clr c            ;  清进位,准备做减法

       subb a,#0bh      ;  各键值和“0BH”比较,大于或等于它证明是符号键
      
       jc   d8          ;  不是符号,还原A

       mov 28h,27h      ;  是符号键,保存键值至内存--28H-----中
      
d8:    mov a,27h        ;  还原A

       LCALL  KEY_BCD    ; 调用键值至BCD码转换子程序
   
       MOV R0,4FH        ; 送键缓存区1首地址----------------

       MOV @R0,A         ; 送至键缓存区1

       CLR   C           ;---------------------

       SUBB A,#0BH       ;  不是数字键和小数点第一个参加运算数结束-----

       JNC  D4           ;  转第一个操作数结束后处理程序

       INC  R0           ;  键缓存区1地址加1 ---------------------

       MOV 4FH,R0        ;  回送存贮指针

       INC   HZ_JS1      ;  键个数加1

D6:    LCALL  XIAN_SHI   ;  调用显示子程序

       MOV A,  HZ_JS1    ;  比较
  
       CJNE A,#13, KEY   ;  个数超过12个第一个操作数输入结束,否则继续读键入值。

D4:    MOV HZ_JS1,#00H   ;
       MOV 4FH,#50H      ;

       MOV 40H,50H       ;  键入的BCD操作数保存       
       MOV 41H,51H       ;
       MOV 42H,52H       ;
       MOV 43H,53H       ;
       MOV 44H,54H       ;
       MOV 45H,55H       ;
       MOV 46H,56H       ;
       MOV 47H,57H       ;
       MOV 48H,58H       ;
       MOV 49H,59H       ;
       MOV 4AH,5AH       ;
       MOV 4BH,5BH       ;
       MOV 4CH,5CH       ;
       MOV 4DH,5DH       ;

       RET               ;

;****************   第一个操作数到四字节浮点BCD转换子程序  *****************

FD_FDBCD: SETB  RS0       ;  使用3区寄存器(18H-1FH)-------3  
           SETB  RS1       ;

           MOV R2,#00H     ;  计数单元清0
      
           MOV  R0, #40H   ;  指向操作数首地址

FD1:       MOV A,@R0       ;  取操作数
         
           CLR   C         ;  为作减法做准备

           SUBB A,#0BH     ;   判断是不是数字键和小数点

           JNC FD3         ;   转操作数个数统计结束后处理程序

FD2:       INC R2          ;  总数字位数加1

           INC R0          ;  操作数指针加1

           AJMP  FD1       ;  返回继续

FD3:       MOV A,  R2      ;  取出总位数

           MOV R3 ,A       ;  保存在R3中

           MOV R4,A        ;  总位数备份,算阶码时用

;---------------  查有无小数点,并统计小数点前面的数字位数----------

           MOV R2,#00H     ;  计数器清0

           MOV R0,#40H     ;  操作数指针

           MOV A,@R0       ;   取数

           CJNE A,#0AH,FD4 ;   比较是否为小数点?

           MOV 30H,#00     ;  说明第一个数是小数点,阶码出了,保存在30H中

;--------------------------- 尾数  1   ----------------------------------------

           INC R0          ;   指向第一个尾数半字节

           INC R2          ;  字个数加1

           MOV  A,R3       ;  取出总字节数
   
           CLR C           ;  作减法准备

           SUBB A,#2       ;  第二字节有数吗

           JNC   FD5       ;  有,没有借位,转继续

           JC   FD21       ;  小数点后什么没有,错误!  

FD5:      MOV A,@R0        ;   取出
         
           ANL  A,#0FH     ;   取后半部分

           SWAP  A         ;   变为高半字节

           MOV B,A         ;  送B中 暂存
   
           INC R0          ;  下一个字节

           INC R2          ;  字个数加1
           
           CLR C           ;  作减法准备

           MOV  A,R3       ;  取出总字节数

           SUBB A,#3       ;  第 3  字节有数吗

           JNC   FD6       ;  有,没有借位,转继续

           MOV A,#00H      ;  没有补0

           AJMP  FD7       ;
  
FD6:      MOV A,@R0       ;  读出

           ANL A,#0FH      ;  取半字节

FD7:      ADD A,B         ;  合成尾数第一个字节

           MOV  31H,A      ;  得到尾数第 1 个字节
           
;-------------------------------------------------------------------   

;--------------------------- 尾数  2  ----------------------------------------

           INC R0          ;   指向尾数半字节

           INC R2          ;   字个数加1

           MOV  A,R3       ;   取出总字节数
   
           CLR C           ;   作减法准备

           SUBB A,#4       ;   第 4 字节有数吗

           JNC   FD8       ;  有,没有借位,转继续

           MOV 32H,#00H    ;  有借位,后两位尾数送0

           MOV 33H,#00H    ;

           AJMP   FD21     ;  转结束

FD8:       MOV A,@R0       ;   取出
         
           ANL  A,#0FH     ;   取后半部分

           SWAP  A         ;   变为高半字节

           MOV B,A         ;  送B中 暂存
   
           INC R0          ;  下一个字节

           INC R2          ;  字个数加1
           
           CLR C           ;  作减法准备

           MOV  A,R3       ;  取出总字节数

           SUBB A,#5       ;  第 5  字节有数吗

           JNC   FD9       ;  有,没有借位,转继续

           MOV A,#00H      ; 没有补0

           AJMP  FD10      ;
  
FD9:      MOV A,@R0       ;  读出

           ANL A,#0FH      ;   取半字节

FD10:      ADD A,B        ;  合成尾数第一个字节

           MOV  32H,A      ;  得到尾数第 2 个字节
           
;-------------------------------------------------------------------            

;--------------------------- 尾数  3 ----------------------------------------

           INC R0          ;   指向尾数半字节

           INC R2          ;  字个数加1

           MOV  A,R3       ;  取出总字节数
   
           CLR C           ;  作减法准备

           SUBB A,#6       ;  第 6 字节有数吗

           JNC   FD11      ;  没有借位,转继续

           MOV 33H,#00H    ;  有借位,最后一个尾数送0
   
           AJMP   FD21     ;  转结束

FD11:      MOV A,@R0       ;   取出
         
           ANL  A,#0FH     ;   取后半部分

           SWAP  A         ;   变为高半字节

           MOV B,A         ;  送B中 暂存
   
           INC R0          ;  下一个字节

           INC R2          ;  字个数加1
           
           CLR C           ;  作减法准备

           MOV  A,R3       ;  取出总字节数

           SUBB A,#7       ;  第 7 字节有数吗

           JNC   FD12      ;  有,没有借位,转继续

           MOV A,#00H      ; 没有补0

           AJMP  FD13      ;
  
FD12:     MOV A,@R0       ;  读出

           ANL A,#0FH      ;   取半字节

FD13:      ADD A,B        ;  合成尾数第一个字节

           MOV  33H,A      ;  得到尾数第 3 个字节
           
;-------------------------------------------------------------------           
           
FD21:     CLR   RS0       ;  恢复使用0区寄存器(00H-07H)
           CLR   RS1       ;

           RET              

           
         
;**************************   第一位不是小数点,操作数处理程序  ********************

;  查整个键入数中有无小数点:1、小数点在中间;2、无小数点      

FD4:   MOV R2,#00H        ;  计数单元清0
      
       MOV  R0, #40H      ;  指向操作数首地址

FD22:  MOV A,@R0          ;  取操作数
      
       CLR C              ;  清进位
  
       SUBB A,#0BH        ;  判断是否为操作符?

       JC  FD23A          ;   是数字或小数点

       JNC  EEROR         ;  第一个数为操作符,提示出错!

EEROR: LJMP  FD21         ;出错返回

FD23A: MOV A,@R0          ;重新取数,上次A已破坏

       CJNE A,#0AH, FD23  ; 和小数点字符值比较,不相等转

       AJMP  FD25         ;  有小数点,并在中间

FD23:  INC R0             ;  指向下一个数

       DJNZ  R3,  FD22    ;  总位数减一,不为0 再循环

;-------------------      以下为无小数点处理程序       --------------------------

FD24:  MOV A,R4           ;  无小数点,总位数是阶码  ,不能用R3,此时它为0;R4也是总位数

       MOV 30H,A          ; 送阶码值到指定单元


;--------------------------- 尾数  1   ----------------------------------------

           MOV R0,#40H     ;  

           MOV R2,#00H     ;

           MOV A,@R0        ;   取出
         
           ANL  A,#0FH     ;   取后半部分

           SWAP  A         ;   变为高半字节

           MOV B,A         ;  送B中 暂存
   
           INC R0          ;  下一个字节

           INC R2          ;  字个数加1
           
           CLR C           ;  作减法准备

           MOV  A,R4       ;  取出总字节数

           SUBB A,#2       ;  第 2  字节有数吗

           JNC   FD25A      ;  没有借位,转继续

           MOV A,#00H      ;  有补0

           AJMP  FD26       ;
  
FD25A:     MOV A,@R0       ;  读出

           ANL A,#0FH      ;  取半字节

FD26:     ADD A,B         ;  合成尾数第一个字节

           MOV  31H,A      ;  得到尾数第 1 个字节
           
;-------------------------------------------------------------------   

;--------------------------- 尾数  2  ----------------------------------------

           INC R0          ;   指向尾数半字节

           INC R2          ;   字个数加1

           MOV  A,R4       ;   取出总字节数
   
           CLR C           ;   作减法准备

           SUBB A,#3       ;   第 3 字节有数吗

           JNC   FD27      ;  有,没有借位,转继续

           MOV 32H,#00H    ;  有借位,后两位尾数送0

           MOV 33H,#00H    ;

           LJMP   FD21     ;  转结束

FD27:       MOV A,@R0      ;   取出
         
           ANL  A,#0FH     ;   取后半部分

           SWAP  A         ;   变为高半字节

           MOV B,A         ;  送B中 暂存
   
           INC R0          ;  下一个字节

           INC R2          ;  字个数加1
           
           CLR C           ;  作减法准备

           MOV  A,R4       ;  取出总字节数

           SUBB A,#4       ;  第 4  字节有数吗

           JNC   FD28      ;  有,没有借位,转继续

           MOV A,#00H      ; 没有补0

           AJMP  FD29      ;
  
FD28:      MOV A,@R0      ;  读出

           ANL A,#0FH      ;   取半字节

FD29:     ADD A,B         ;  合成尾数第一个字节

           MOV  32H,A      ;  得到尾数第 2 个字节
           
;-------------------------------------------------------------------            

;--------------------------- 尾数  3 ----------------------------------------

           INC R0          ;   指向尾数半字节

           INC R2          ;  字个数加1

           MOV  A,R4       ;  取出总字节数
   
           CLR C           ;  作减法准备

           SUBB A,#5       ;  第 5 字节有数吗

           JNC   FD30      ;  没有借位,转继续

           MOV 33H,#00H    ;  有借位,最后一个尾数送0
   
           AJMP   FD21     ;  转结束

FD30:      MOV A,@R0       ;   取出
         
           ANL  A,#0FH     ;   取后半部分

           SWAP  A         ;   变为高半字节

           MOV B,A         ;  送B中 暂存
   
           INC R0          ;  下一个字节

           INC R2          ;  字个数加1
           
           CLR C           ;  作减法准备

           MOV  A,R4       ;  取出总字节数

           SUBB A,#6       ;  第 6 字节有数吗

           JNC   FD31      ;  有,没有借位,转继续

           MOV A,#00H      ;  没有补0

           AJMP  FD32      ;
  
FD31:     MOV A,@R0       ;  读出

           ANL A,#0FH      ;  取半字节

FD32:      ADD A,B        ;  合成尾数第一个字节

           MOV  33H,A      ;  得到尾数第 3 个字节

           LJMP   FD21     ;  转出口
           
;-----------------------以下为小数点在中间处理程序  -------------------------------------------           

FD25:      
           MOV R2,#00H       ;  计数器清0

           MOV R0,#40H       ;  操作数指针

FD34:      MOV A,@R0         ;   取数

           CJNE A,#0AH,FD33  ;   比较是否为小数点?

           MOV  A,R2         ;   取出计数值

           MOV 30H, A        ;   送阶码

           AJMP  FD35       ;   转出处理尾数

FD33:      INC R2            ;  未找到,加一继续
         
           INC R0            ;  指针加1

           DJNZ  R4,   FD34  ;  总位数减一循环-----原为R3,不能用,至4位时就出错!

FD35:     
        ;--------------------------- 尾数  1   ----------------------------------------

           MOV R0,#40H     ;  指向首地址

           MOV R1,#34H     ;  指向暂存首地址

           MOV R5,#07      ;  总共取7次,包括一个小数点

FD37:      MOV A,@R0       ;  取出数

           CJNE A,#0AH,FD36;  比较是否为小数点,不是转

           INC R0         ;   是小数点跳过一个字节

           MOV A,@R0       ;   取下一个单元

FD36:      MOV @R1,A       ;   存入缓冲单元

           INC  R0         ;   调整源指针

           INC  R1         ;   调整暂存指针

           DJNZ R5, FD37   ;   循环取7次,有小数点时得到六个数,无小数点时得到7个数。

;----------------------  尾数 1  -------------------------------
           MOV  A,34H      ;   取一个数

           SWAP  A         ;   高低四位交换

           ADD A,35H       ;   和下位合成

           MOV 31H,A       ;   送尾数
;------------------------------------------------------------  

;----------------------  尾数 2  -------------------------------

           MOV  A,36H      ;   取一个数

           SWAP  A         ;   高低四位交换

           ADD A,37H       ;   和下位合成

           MOV 32H,A       ;   送尾数
;------------------------------------------------------------

;----------------------  尾数 3  -------------------------------

           MOV  A,38H      ;   取一个数

           SWAP  A         ;   高低四位交换

           ADD A,39H       ;   和下位合成

           MOV 33H,A       ;   送尾数
;------------------------------------------------------------                                       
         
            LJMP FD21       ;返回出口

;*********************************************************

               

;*******************************************************************
KEY_BCD:  MOV DPTR,#TAB1    ;

           MOVC  A,@A+DPTR   ;

           RET
;****************************************************************************

TAB1: DB  00H,01H,02H,03H,04H,05H,06H,07H  ;  --0--1--2--3--4--5--6--7  
       DB  08H,09H,0AH,0BH,0CH,0DH,0EH,0FH  ;  --8--9--"DP"--"+"--"-"--"*"--"/"
       DB  10H,11H,12H,13H,14H,15H,16H,17H  ;  --CE--"="--"M+"--"C"--SIN--COS--TAN--EXP
;***************************************************************************************

XIAN_SHI :

;-----------------1------------------
             MOV A, 50H       ;  显示子程序 ,显示50H---5BH 内容

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;

             MOV 26H,A        ;  缓存单元

             MOV A,25H        ;  阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS1 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS2         ;  是在键盘壮态

XS1:        CJNE A,#00H,XS3  ;  在显示壮态下再分析是否为00---0. ,这时应显示0

             MOV 26H,#0FCH    ;  显示 0

             AJMP  XS2        ;

XS3:        MOV 26H,#00H     ;  其它壮态不显示         

XS2:        MOV A,26H        ;      

             MOV P1,A         ;

             SETB P2.0        ;

             LCALL  DELAY1    ;

             CLR    P2.0      ;
            
;------------------2------------------
             MOV A, 51H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;

             MOV 26H,A        ;  缓存单元

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS5 ; 区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS4         ;  是在键盘壮态

XS5:         CJNE A,#00H,XS6  ;  在显示壮态下再分析是否为00---0. ,这时应显示  "."

             MOV 26H,#01H    ;  显示 " . "

             AJMP  XS4       ;

XS6:        MOV 26H,#00H     ;  其它壮态不显示         

XS4:        MOV A,26H        ;
            
             MOV P1,A         ;

             SETB P2.1        ;

             LCALL  DELAY1    ;

             CLR    P2.1      ;
         
;-------------------3---------------------
             MOV A, 52H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;
              
             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS7 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS8         ;  是在键盘壮态

XS7:         CJNE A,#01H,XS8  ;  在显示壮态下再分析是应显示  "."

             INC  26H         ;  显示 " X. "

XS8:         MOV A,26H        ;

             MOV P1,A         ;

             SETB P2.2        ;

             LCALL  DELAY1    ;

             CLR    P2.2      ;
            
  ;------------------4----------------------
             MOV A, 53H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;

             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS9 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS10         ;  是在键盘壮态

XS9:         CJNE A,#02H,XS10  ;  在显示壮态下再分析是应显示  "."

             INC  26H         ;  显示 " X. "

XS10:        MOV A,26H        ;


             MOV P1,A         ;

             SETB P2.3       ;

             LCALL  DELAY1    ;

             CLR    P2.3      ;
;---------------------5-------------------
             MOV A, 54H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;
           
             MOV 26H,A         ;  缓存单元保存A

             MOV A,25H         ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS11 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS12         ;  是在键盘壮态

XS11:         CJNE A,#03H,XS12 ;  在显示壮态下再分析是应显示  "."

              INC  26H         ;  显示 " X. "

XS12:         MOV A,26H        ;

              MOV P1,A         ;

              SETB P2.4        ;

             LCALL  DELAY1     ;

             CLR    P2.4       ;
;----------------------6------------------
             MOV A, 55H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;

             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS13 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS14         ;  是在键盘壮态

XS13:         CJNE A,#04H,XS14  ;  在显示壮态下再分析是应显示  "."

              INC  26H         ;  显示 " X. "

XS14:         MOV A,26H        ;

             MOV P1,A         ;

             SETB P2.5      ;

             LCALL  DELAY1    ;

             CLR    P2.5      ;
;-----------------------7-----------------
             MOV A, 56H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;

             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS15 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS16        ;  是在键盘壮态

XS15:         CJNE A,#05H,XS16  ;  在显示壮态下再分析是应显示  "."

              INC  26H         ;  显示 " X. "

XS16:         MOV A,26H        ;

              MOV P1,A         ;

             SETB P2.6        ;

             LCALL  DELAY1    ;

             CLR    P2.6      ;
;------------------------8----------------
             MOV A, 57H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;

             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS17 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS18         ;  是在键盘壮态

XS17:         CJNE A,#06H,XS18  ;  在显示壮态下再分析是应显示  "."

             INC  26H         ;  显示 " X. "

XS18:         MOV A,26H        ;


             MOV P1,A         ;

             SETB P2.7        ;

             LCALL  DELAY1    ;

             CLR    P2.7      ;
;-------------------------9---------------
             MOV A, 58H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;
            
             MOV 26H,A         ;  缓存单元保存A

             MOV A,25H         ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS19  ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS20         ;  是在键盘壮态

XS19:        CJNE A,#07H,XS20   ;  在显示壮态下再分析是应显示  "."

             INC  26H          ;  显示 " X. "

XS20:         MOV A,26H        ;

             MOV P1,A          ;

             SETB P0.7         ;

             LCALL  DELAY1    ;

             CLR    P0.7      ;
;--------------------------10--------------
             MOV A, 59H

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;
            
             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS21 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS22         ;  是在键盘壮态

XS21:         CJNE A,#08H,XS22  ;  在显示壮态下再分析是应显示  "."

             INC  26H         ;  显示 " X. "

XS22:         MOV A,26H        ;

             MOV P1,A         ;

             SETB P0.6     ;

             LCALL  DELAY1    ;

             CLR    P0.6      ;
;------------------------11----------------
             MOV A, 5AH

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;
            
             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS23 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS24         ;  是在键盘壮态

XS23:         CJNE A,#09H,XS24  ;  在显示壮态下再分析是应显示  "."

             INC  26H         ;  显示 " X. "

XS24:         MOV A,26H        ;

              MOV P1,A         ;

              SETB P0.5        ;

             LCALL  DELAY1    ;

             CLR    P0.5      ;
;-------------------12---------------------
             MOV A, 5BH

             ANL A,#0FH       ;

             MOV DPTR,#TAB2   ;
  
             MOVC A,@A+DPTR   ;
            
             MOV 26H,A        ;  缓存单元保存A

             MOV A,25H        ;   阶码存放单元,在键盘壮态时为0FFH

             CJNE A,#0FFH,XS25 ;  区分是键盘显示还是运算结果显示---键盘标致为0FFH               
         
             AJMP XS26         ;  是在键盘壮态

XS25:         CJNE A,#0AH,XS26  ;  在显示壮态下再分析是应显示  "."

              INC  26H         ;  显示 " X. "

XS26:        MOV A,26H        ;

             MOV P1,A         ;

             SETB P0.4     ;

             LCALL  DELAY1    ;

             CLR    P0.4      ;

              RET

TAB2:  DB  0FCH,060H,0DAH,0F2H,066H,0B6H,0BEH,0E0H,0FEH,0F6H,01H,00H  ; -0-1-2-3-4-5-6-7-8-9-.-空

;**********************************************

DELAY1:  MOV R7,#03   ;-------03

DD1:    MOV R6,#248   ;-------248

         DJNZ R7,  DD1  ;

         RET
;*********************************************

;***************************************************
DISPLAY_CLR:

       MOV 50H, #00H     ; 显示单元清0
       MOV 51H, #00H     ;
       MOV 52H, #00H     ;
       MOV 53H, #00H     ;
       MOV 54H, #00H     ;
       MOV 55H, #00H     ;
       MOV 56H, #00H     ;
       MOV 57H, #00H     ;
       MOV 58H, #00H     ;
       MOV 59H, #00H     ;
       MOV 5AH, #00H     ;
       MOV 5BH, #00H     ;

       RET
;***************************************************


;测试程序---------2008/01/06
;     ORG   0000H

;        MOV SP,#60H;

;     MOV 30H,#83H;A
;        MOV 31H,#12H;
;     MOV 32H,#34H;
;        MOV 33H,#56H;

;     MOV 34H,#00H;B
;        MOV 35H,#75H;
;     MOV 36H,#77H;
;        MOV 37H,#12H;

;        MOV 38H,#02H;C
;        MOV 39H,#56H;
;     MOV 3AH,#34H;
;        MOV 3BH,#12H;

;        MOV 3CH,#01H;D
;        MOV 3DH,#12H;
;     MOV 3EH,#76H;
;        MOV 3FH,#23H;


;以浮点运算为例, 计算y=ab/c+d 。
;已知:a =-123.456,b=0.757 712,c=56.3412,d=
;1.276 23; 它们分别存放在30H开始的连续单元中。
;用BCD 码浮点数表示时,分别为a=831 234 56H,
;b=007 577 12H, c=025 634 12H, d=011 276 23H。
;求解过程:通过调用BTOF子程序,将各变量
;转换成二进制浮点操作数,再进行各种运算,最后
;调用FTOB子程序,还原成十进制形式,供输出使
;用。程序如下:

;TEST:
;MOV R0,#3CH    ;  指向BCD 码浮点操作数d---D的首地址

;LCALL BTOF     ;  将其转换成二进制浮点操作数

;MOV R0,#38H    ; 指向BCD 码浮点操作数c---C的首地址

;LCALL BTOF     ; 将其转换成二进制浮点操作数

;MOV R0,#34H    ; 指向BCD 码浮点操作数b--B的首地址

;LCALL BTOF     ; 将其转换成二进制浮点操作数

;MOV R0,#30H    ; 指向BCD 码浮点操作数a----A的首地址

;LCALL BTOF     ; 将其转换成二进制浮点操作数

;MOV R1,#34H    ; 指向二进制浮点操作数b

;LCALL FMUL     ; 进行浮点乘法运算-------A×B

;MOV R1,#38H    ; 指向二进制浮点操作数c

;LCALL FDIV     ; 进行浮点除法运算-------A×B/C

;MOV R1,#3CH    ; 指向二进制浮点操作数d

;LCALL FADD     ; 进行浮点加法运算--------A*B/C+D

;LCALL FTOB     ; 将结果转换成BCD 码浮点数

NOP
NOP

;STOP: LJMP STOP

;运行结果,[R0]=80384084H, 即y = -0.384 084,
;比较精确的结果应该是-0.384 084 1。
;程序清单见本刊网络补充版(ht tp:/ /www.dpj.
;com.cn)。


;MCS-51四字节浮点库及其使用说明
;浮点库程序清单如下:
;程序清单:
;(1) 标号: BTOF 功能:浮点BCD码转换成格式化浮点数
;入口条件:浮点BCD码操作数在[R0]中。
;出口信息:转换成的格式化浮点数仍在[R0]中。
BTOF: INC R0
INC R0
inc r0;read L
MOV 07h,@R0
DEC R0
MOV 06h,@R0
DEC R0
mov 05h,@r0
;r5r6r7=0.hml(dec)
dec r0 ;;r0 to jie_ma
mov a,r7
ORL A,R6
orl a,r5
jnz btf0 ;jb r5r6r7=0
MOV @R0,#41H
RET

BTF0: MOV A,@R0
MOV C,ACC.7
MOV 1DH,C
CLR 1FH
MOV C,ACC.6
MOV ACC.7,C
MOV @R0,A
JNC BTF1
ADD A,#19
JC BTF2
MOV @R0,#41H;
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
inc r0
MOV @R0,#0
DEC R0
DEC R0
dec r0
RET

BTF1: SUBB A,#19
JC BTF2
MOV A,#3FH
MOV C,1DH
MOV ACC.7,C
MOV @R0,A
INC R0
MOV @R0,#0FFH
INC R0
MOV @R0,#0FFH
inc r0
MOV @R0,#0FFH
dec r0
DEC R0
DEC R0
RET

BTF2: CLR A ;use r1.r2r3r4
MOV R4,A
MOV R3,A
MOV R2,a
mov r1,#24 ;3byte =3*8=24
BTF3: MOV A,R7
ADD A,R7
DA A
MOV R7,A
MOV A,R6
ADDC A,R6
DA A
MOV R6,A
mov a,r5
addc a,r5
da a
mov r5,a;r5r6r7*2
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
mov a,r2
rlc a
mov r2,a ;count .r5r6r7(10)=>.r2r3r4(2)
DEC R1
JNB ACC.7,BTF3
MOV A,R5
ADD A,#0B0H
CLR A
ADDC A,R4
MOV R4,A
CLR A
ADDC A,R3
MOV R3,A
CLR A
ADDC A,R2
MOV R2,A
JNC BTF4
MOV R2,#80H
INC R1
BTF4:
MOV DPTR,#BTFL
MOV A,@R0
ADD A,#19
MOV B,#4  ;4 byte
MUL AB
ADD A,DPL
MOV DPL,A
JNC BTF5
INC DPH
BTF5: CLR A
MOVC A,@A+DPTR
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A  ;r4'=0ch
MOV A,#1
MOVC A,@A+DPTR
MOV 0dh,A
MOV A,#2
MOVC A,@A+DPTR
MOV 0eh,A
MOV A,#3
MOVC A,@A+DPTR
MOV 0fh,A
LCALL MUL1
MOV C,1DH
MOV 1FH,C
LJMP MOV0

;(2) 标号: FTOB 功能:格式化浮点数转换成浮点BCD码---------------
;入口条件:格式化浮点操作数在[R0]中。
;出口信息:转换成的浮点BCD码仍在[R0]中。
FTOB: INC R0
MOV A,@R0 ;h
INC R0
ORL A,@R0 ;m
inc r0
orl a,@r0 ;l
dec r0
DEC R0
DEC R0
JNZ FTB0
MOV @R0,#41H
RET
FTB0: MOV A,@R0
MOV C,ACC.7
MOV 1DH,C
CLR ACC.7
MOV @R0,A
LCALL MVR0
MOV DPTR,#BFL0
MOV B,#0
MOV A,R2
JNB ACC.7,FTB1
MOV DPTR,#BTFL
MOV B,#0EDH
ADD A,#16
JNC FTB1
MOV DPTR,#BFLN
MOV B,#0FAH
FTB1: CLR A
MOVC A,@A+DPTR
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4'
MOV A,#1
MOVC A,@A+DPTR
MOV 0dh,A
MOV A,#2
MOVC A,@A+DPTR
MOV 0eh,A
MOV A,#3
MOVC A,@A+DPTR
MOV 0fh,A
MOV A,0ch  ;r4' jie_ma
CLR C
SUBB A,R2
JB ACC.7,FTB2
JNZ FTB3
MOV A,0dh  ;0.r5'r6'r7'-0.r3r4r5
CLR C
SUBB A,R3
JC FTB2
JNZ FTB3
MOV A,0eh;r6'-r4;;;2002.6.18
CLR C
SUBB A,r4
JC FTB2
JNZ FTB3
MOV 0ah,B
INC 0ah
MOV 0dh,#10h;0.100000
MOV r6,#0
MOV r7,#0
SJMP FTB6
FTB2: INC DPTR
INC DPTR
INC DPTR
inc dptr   ;4byte
INC B
SJMP FTB1  
FTB3: PUSH B
CALL DIV3
FTB4: MOV A,r2
JZ FTB5
CLR C
LCALL RR1
SJMP FTB4
FTB5:
POP 0ah
LCALL HB2
MOV 0dh,A;r5'
LCALL HB2
MOV R6,A
LCALL HB2
MOV R7,A
MOV A,R3
RLC A
CLR A
ADDC A,R7
DA A
MOV R7,A
CLR A
ADDC A,R6
DA A
MOV R6,A
JNC FTB6
MOV R6,#10H
INC 0dh
FTB6:
INC R0
INC R0
inc r0
MOV A,R7
MOV @R0,A
DEC R0
MOV A,R6
MOV @R0,A
DEC R0
MOV A,0dh
mov @r0,a
dec r0
mov a,0ah
MOV C,1DH
MOV ACC.7,C
MOV @R0,A
RET
;[r3r4r5*100]\10=>bcd1,2
HB2:
MOV A,R5
MOV B,#100
MUL AB
MOV R5,A
MOV A,B
XCH A,R4
MOV B,#100
MUL AB
ADD A,R4
MOV R4,A
;JNC HB21
mov a,B
addc a,#0
xch a ,r3
mov b,#100
mul ab
add a,r3
mov r3,a
mov a,b
addc a,#0
HB21: ;MOV A,B
MOV B,#10
DIV AB
SWAP A
ORL A,B
RET
BTFL: DB 41H,0ECH,1EH ,4ah;10e-19
DB 45H,93H,92H,0efh;10e-18   
DB 48H,0B8H,77H,0aah;10e-17
DB 4BH,0E6H,95H,95h;10e-16
DB 4FH,90H,1DH ,7dh;10e-15
DB 52H,0B4H,24H,0dch;10e-14
DB 55H,0E1H,2EH,13h;10e-13
DB 59H,8CH,0BcH,0cch;10e-12
DB 5CH,0AFH,0EbH,0ffh;10e-11
DB 5FH,0DBH,0E6H,0ffh;10e-10
DB 63H,89H,70H ,5fh;10e-9
DB 66H,0ABH,0CCH,77h;10e-8
DB 69H,0D6H,0bfH,95h;10e-7
BFLN: DB 6DH,86H,37H ,0bdh;10e-6
DB 70H,0A7H,0C5H,0ach;10e-5
DB 73H,0D1H,0B7H,17h;10e-4
DB 77H,83H,12H ,6fh;10e-3
DB 7AH,0A3H,0D7H,0ah;10e-2
DB 7DH,0CCH,0CcH,0cdh;10e-1
BFL0: DB 1,80H,00H ,00h;10e0
DB 4,0A0H,00H,00h;10e1
DB 7,0C8H,00H,00h;10e2
DB 0AH,0FAH,00H,00h;10e3
DB 0EH,9CH,40H,00h;10e4
DB 11H,0C3H,50H,00;10e5
DB 14H,0F4H,24H,00h;10e6
DB 18H,98H,96H,80h;10e7
DB 1BH,0BEH,0BCH,20h;10e8
DB 1EH,0EEH,6BH,28h;10e9
DB 22H,95H,02H,0f9h;10e10
DB 25H,0BAH,43H,0b7h;10e11
DB 28H,0E8H,0D4h,0a5h;10e12
DB 2CH,91H,84H,0e7h;10e13
DB 2FH,0B5H,0E6H,20h;10e14
DB 32H,0E3H,5fH,0a9h;10e15
DB 36H,8EH,1bH,0cah;10e16
DB 39H,0c1H,0A2H,0cdh;10e17
DB 3CH,0DEH,0BH,5bh;10e18
DB 40H,8AH,0d7H,23h;10e19
;(3) 标号: FMUL 功能:浮点数乘法
;入口条件:被乘数在[R0]中,乘数在[R1]中。
;出口信息:OV=0时,积仍在[R0]中,OV=1时,溢出。
FMUL: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV 1FH,C
LCALL MUL0
LJMP MOV0
MUL0: LCALL MVR1
mov 01h,02h
mov 02h,03h
mov 03h,04h
mov 04h,05h
;;**************8
MUL1:
;***********
MOV A,R2 ;;第一尾数为零否?
ORL A,R3
orl a,r4
JZ MUL6
MOV A,0dh ;;第二尾数为零否?
ORL A,0eh
orl a,0fh
JZ MUL5;计算r2R3R4×r5R6R7-→r2R3R4
;************
mov 08h,r0;jie_ma piont
mov 09h,r1;jie_ma
mov 01h,r2
mov 02h,r3
mov 03h,r4
;************
MOV R0,#25;右移相加25次
CLR A
MOV R6,A
MOV R7,A;ACC,R6,R7为部分积累加器
CLR C
LOOP1:JNC M2
CALL ADD0
ADDC A,R1;乘数移出位等于1 ,被乘数往部分积里加1次
M2:CALL SRA1
XCH A,R5
CPL RS0
CALL SRA
CPL RS0;部分积带进位位整体右移1位
DJNZ R0,LOOP1
MOV R5,A
JB  ACC.7,M3;查积最高位
MOV A,0DH
RLC A
CALL H0;积最高位为0,积整体算术左移1位
JNB  ACC.7,Mul3
CALL INC3;尾数截去部分四舍五入
SJMP mul3
M3:
MOV A,0DH
JNB ACC.7,mul3;2002
CALL INC3;尾数截去部分四舍五入
;sjmp mul3

;***************
MUL3:
;***********
mov r0,08h
mov 03h,r5
mov 04h,r6
mov 05h,r7
;*************
MOV A,09h
ADD A,0ch
MD: MOV r2,A
JB ACC.7,MUL4
JNB ACC.6,MUL6
MOV r2,#3FH
SETB OV
RET
MUL4: JB ACC.6,MUL6
MUL5:
CLR A
mov r5,a     ;out r2.r3r4r5=fu(2)
MOV R3,A
MOV R4,A
MOV R2,#41H
MUL6: CLR OV
RET
;(4) 标号: FDIV 功能:浮点数除法
;入口条件:被除数在[R0]中,除数在[R1]中。
;出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。
FDIV:
INC R0
MOV A,@R0
INC R0
ORL A,@R0
inc r0
orl a,@r0
dec r0
DEC R0
DEC R0
JNZ DIV1
MOV @R0,#41H
CLR OV
RET
DIV1: INC R1
MOV A,@R1
INC R1
ORL A,@R1
inc r1
orl a,@r1
dec r1
DEC R1
DEC R1
JNZ DIV2
SETB OV
RET
DIV2: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV 1FH,C
LCALL MVR1
LCALL DIV3
LJMP MOV0
DIV3: CLR C ;r3r4r5-r5'r6'r7'
MOV A,R5    ;A<b to count
SUBB A,0fh
mov a,r4
subb a,0eh
mov a,r3
subb a,0dh
JC DIV4
CALL RR1
SJMP DIV3
DIV4:
mov 08h,r0
mov 09h,r1
mov 0ah,r2
CLR A
mov r0,a
mov r1,a
mov r2,a
MOV B,#24     ;r3r4r5/r5'r6'r7'=>r0r1r2
DIV5: CLR C
mov a,r2
rlc a
mov r2,a
MOV A,R1
RLC A
MOV R1,A
MOV A,R0
RLC A
MOV R0,A
MOV A,R5
RLC A
MOV R5,A
XCH A,R4
RLC A
XCH A,R4
XCH A,R3
RLC A
XCH A,R3
MOV F0,C
CLR C
SUBB A,0fh;r7'
MOV r7,A  ;r7 temp
MOV A,R4
SUBB A,0eh
MOV r6,A  
MOV A,R3
SUBB A,0dh
ANL C,/F0
JC DIV6
MOV R3,A
MOV 05h,07h;r7
mov 04h,06h
INC R2
DIV6: DJNZ B,DIV5
MOV A,0dh
CLR C
RRC A
SUBB A,R3
CLR A
ADDC A,R2
MOV R5,A
CLR A
ADDC A,R1
MOV R4,A
CLR A
ADDC A,R0
MOV R3,A
mov r0,08h
mov r1,09h
mov r2,0ah
MOV A,R2
CLR C
SUBB A,0ch
LCALL MD
LJMP RLN
;(5) 标号: FMOV 功能:浮点数传送
;入口条件:源操作数在[R1]中,目标地址为[R0]。
;出口信息:[R0]=[R1],[R1]不变。
FMOV: INC R0
INC R0
inc r0
INC R1
INC R1
inc r1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
RET
;(6) 标号: FCMP 功能:浮点数代数值比较(不影响待比较操作数)
;入口条件:待比较操作数分别在[R0]和[R1]中。
;出口信息:若CY=1,则[R0] < [R1],若CY=0且A=0则 [R0] = [R1],否则[R0] > [R1]。
FCMP: MOV A,@R0
XRL A,@R1
JNB ACC.7,CMP2
MOV A,@R0
RLC A
MOV A,#0FFH
RET
CMP2: MOV A,@R1
MOV C,ACC.6
MOV ACC.7,C
MOV B,A
MOV A,@R0
MOV C,ACC.7
MOV F0,C
MOV C,ACC.6
MOV ACC.7,C
CLR C
SUBB A,B
JZ CMP6
RLC A
JNB F0,CMP5
CPL C
CMP5: MOV A,#0FFH
RET
;************
CMP6:
INC R0
INC R0
inc r0
inc r1
INC R1
INC R1
CLR C
MOV A,@R0
SUBB A,@R1
MOV B,A
DEC R0
DEC R1
MOV A,@R0
SUBB A,@R1
DEC R0
DEC R1
;***********
mov 0fh,a;r7'
MOV A,@R0
SUBB A,@R1
dec r0
dec r1
ORL A,0fh
orl a,b
JZ CMP7
JNB F0,CMP7
CPL C
CMP7: RET
;(7) 标号: FADD 功能:浮点数加法
;入口条件:被加数在[R0]中,加数在[R1]中。
;出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。
FADD: CLR F0;簧枇⒓臃ū曛?
SJMP AS ;患扑愦?
FADD1: CLR F0 ; -------------------------
SJMP AS

;(8) 标号: FSUB 功能:浮点数减法
;入口条件:被减数在[R0]中,减数在[R1]中。
;出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。
FSUB: SETB F0
AS: LCALL MVR1
MOV C,F0
RRC A
XRL A,@R1
MOV C,ACC.7
ASN: MOV 1EH,C
XRL A,@R0
RLC A
MOV F0,C
LCALL MVR0
LCALL AS1
MOV0:
INC R0
INC R0
inc r0
mov a,r5
mov @r0,a
dec r0
MOV A,R4
MOV @R0,A
DEC R0
MOV A,R3
MOV @R0,A
DEC R0
MOV A,R2
MOV C,1FH
MOV ACC.7,C
MOV @R0,A
CLR ACC.7
CLR OV
CJnE A,#3FH,MV01
SETB OV
MV01: MOV A,@R0
RET

MVR0: MOV A,@R0
MOV C,ACC.7
MOV 1FH,C
MOV C,ACC.6
MOV ACC.7,C
MOV R2,A
INC R0
MOV A,@R0
MOV R3,A
INC R0
MOV A,@R0
MOV R4,A
inc r0
mov a,@r0
mov r5,a
dec r0
DEC R0
DEC R0
RET
MVR1: MOV A,@R1
MOV C,ACC.7
MOV 1EH,C
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4'
INC R1
MOV A,@R1
MOV 0dh,A
INC R1
MOV A,@R1
MOV 0eh,A
INC R1
MOV A,@R1
MOV 0fh,A
dec r1
DEC R1
DEC R1
RET
AS1:
MOV A,0dh
ORL A,0eh
orl a,0fh
JZ AS2
MOV A,R3
ORL A,R4
orl a,r5
JNZ EQ1
mov r3,0dh
mov r4,0eh
mov r5,0fh ;a2=>a1
;************
MOV r2,0ch
;************
MOV C,1EH
MOV 1FH,C
AS2: RET
EQ1: MOV A,R2
XRL A,0ch ;jie_ma
JZ AS4
JB ACC.7,EQ3
MOV A,R2
CLR C
SUBB A,0ch
JC EQ4
EQ2: CLR C
MOV A,0dh
RRC A
MOV 0dh,A
MOV A,0eh
RRC A
MOV 0eh,A
MOV A,0fh
RRC A
MOV 0fh,A
;**********
INC 0ch
;**********
ORL A,0eh
orl a,0dh
JNZ EQ1
MOV A,R2
MOV 0ch,A ;r4'
SJMP AS4
EQ3: MOV A,R2
JNB ACC.7,EQ2
EQ4: CLR C
LCALL RR1
;*************8
orl a,r4
ORL A,R3
JNZ EQ1
MOV A,0ch
MOV R2,A
AS4: JB F0,AS5
;****************
MOV A,R5
ADD A,0fh
MOV R5,A
MOV A,R4
ADDC A,0eh
MOV R4,A

MOV A,R3
ADDC A,0dh
MOV R3,A

JNC AS2
LJMP RR1
AS5: CLR C
MOV A,R5
SUBB A,0fh
MOV B,A
;************
MOV A,R4
SUBB A,0eh
mov r6,a;*****temp
MOV A,R3
SUBB A,0dh
JC AS6
MOV R5,B
MOV R3,A
mov r4,06h
LJMP RLN
AS6: CPL 1FH
CLR C
MOV A,0fh
SUBB A,R5
MOV R5,A
MOV A,0eh
SUBB A,R4
MOV R4,A
MOV A,0dh
SUBB A,R3
MOV R3,A
RLN: MOV A,R3
ORL A,R4
orl a,r5;****2002.6.18
JNZ RLN1
MOV R2,#0C1H
RET
RLN1: MOV A,R3
JB ACC.7,RLN2
CLR C
LCALL RL1
SJMP RLN
RLN2: CLR OV
RET
;*****************
RL1:
MOV A,R5
RLC A
MOV R5,a
;*******
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
DEC R2
CJNE R2,#0C0H,RL1E
CLR A
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#0C1H
RL1E: CLR OV
RET
RR1: MOV A,R3
RRC A
MOV R3,A
MOV A,R4
RRC A
MOV R4,A
;*********
MOV A,R5
RRC A
MOV R5,A
;***********
INC R2
CLR OV
CJNE R2,#40H,RR1E
MOV R2,#3FH
SETB OV
RR1E: RET
;(9)标号: DTOF 功能:三字节十六进制定点数转换成格式化浮点数
;入口条件:三字节定点数的绝对值在[R0]中,数符在位1FH中,整数部分的位数在A中。
;出口信息:转换成格式化浮点数在[R0]中(四字节)。
DTOF:
MOV R2,A ;;按整数的位数初始化阶码
MOV 03h,@R0 ;;将定点数作尾数
INC R0
MOV 04h,@R0
inc r0
mov 05h,@r0
dec r0
DEC R0
LCALL RLN ;;进行规格化
LJMP MOV0 ;;传送结果到[R0]中
;(10) 标号: FINT 功能:浮点取整函数
;入口条件:操作数在[R0]中。
;出口信息:结果仍在[R0]中。
FINT: LCALL MVR0
LCALL INT
LJMP MOV0
;****************
INT:
MOV A,R3
ORL A,R4
orl a,r5
JNZ INTA
CLR 1FH
MOV R2,#41H
RET
INTA: MOV A,R2
JZ INTB
JB ACC.7,INTB
CLR C
SUBB A,#24 ;;24 wei
JC INTD
RET
INTB: CLR A
MOV R5,A
MOV R4,A
MOV C,1FH
rrc a
MOV R3,A
Rl A   ;2002.6.20!!!!!!!!!!
MOV R2,A
JNZ INTC
MOV R2,#41H
INTC: RET
INTD: CLR F0
INTE: CLR C
LCALL RR1
ORL C,F0
MOV F0,C
CJNE R2,#24,INTE
JNB F0,INTF
JNB 1FH,INTF
INC R5
MOV A,R5
JNZ INTF
mov a,r4
add a,#01;;;;in
mov a,r3
addc a,#00
INTF: LJMP RLN
ADD0:CLR C;双精度加法子程序
ADC0:XCH A,R7;双精度带进位位加法子程序
ADDC  A,R3
XCH   A,R7
XCH   A,R6
ADDC  A,R2
XCH   A,R6
RET
SRA0:CLR C;尾数逻辑右移1位子程序
SRA:XCH  A,R5;尾数带进位位右移1位
SRA1:RRC A;A R6 R7带进位位右移1位,结果在R5 R6 R7中
XCH  A,R5
XCH  A,R6
RRC  A
XCH  A,R6
XCH  A,R7
RRC  A
XCH  A,R7
RET
INC3:
mov a,r7
add a,#1
mov r7,a
mov a,r6
addc a,#0
mov r6,a
mov a,r5
addc a,#0
jnz inc321
mov a,#80h
inc321:
mov r5,a
mov a,09h
addc a,#0;2002.6.18
mov 09h,a
RET0:RET
H0:
XCH A,R7;尾数带进位左移1位
RLC  A
XCH  A,R7
XCH  A,R6
RLC  A
XCH  A,R6
XCH  A,R5
RLC  A
XCH  A,R5
push acc
dec 09h
mov a,09h
CJNE a,#0C0H,RL1E11
MOV R5,#0
MOV R6,#0
mov r7,#0
MOV 09h,#0C1H
RL1E11:
pop acc
CLR OV
RET
;(11)标号: FSGN 功能:浮点符号函数
;入口条件:操作数在[R0]中。
;出口信息:累加器 A=1 时为正数,A=0FFH时为负数,A=0 时为零。
FSGN: INC R0 ;;读尾数
MOV A,@R0
INC R0
ORL A,@R0
INC R0
ORL A,@R0
dec r0
DEC R0
DEC R0
JNZ SGN
RET ;;尾数为零,结束
SGN: MOV A,@R0 ;;读取操作数的阶码
RLC A ;;取数符
MOV A,#1 ;;按正数初始化
JNC SGN1 ;;是正数,结束
MOV A,#0FFH ;;是负数,改变标志
SGN1: RET
;(12) 标号: FCLR 功能:浮点数清零
;入口条件:操作数在[R0]中。
;出口信息:操作数被清零。
FCLR:
INC R0
INC R0
inc r0
CLR A
MOV @R0,A
DEC R0
MOV @R0,A
DEC R0
MOV @R0,A
DEC R0
MOV @R0,#41H
RET
;(13) 标号: FZER 功能:浮点数判零
;入口条件:操作数在[R0]中。
;出口信息:若累加器A为零,则操作数[R0]为零,否则不为零。
FZER:
INC R0
mov a,@r0
INC R0
orl A,@R0
inc r0
orl a,@r0
dec r0
DEC R0
DEC R0
JNZ ZERO
MOV @R0,#41H
ZERO: RET
;(14) 标号: FPUSH 功能:浮点数压栈
;入口条件:操作数在[R0]中。
;出口信息:操作数压入栈顶。
FPUSH: POP ACC ;将返回地址保存在R2R3r4中
MOV R2,A
POP ACC
MOV R3,A
pop acc
mov r4,a
;*******
MOV A,@R0 ;将操作数压入堆栈
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
inc r0
mov a,@r0
push acc
dec r0
DEC R0
DEC R0
mov a,r4
push acc
MOV A,R3 ;将返回地址压入堆栈
PUSH ACC
MOV A,R2
PUSH ACC
RET
;***************
;(15) 标号: FPOP 功能:浮点数出栈
;入口条件:操作数处于栈顶。
;出口信息:操作数弹至[R0]中。
FPOP: POP ACC ;将返回地址保存在R2R3r4中
MOV R2,A
POP ACC
MOV R3,A
pop acc
mov r4,a
;**********
INC R0
INC R0
inc r0
POP ACC ;将操作数弹出堆栈,传送到[R0]中
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
dec r0
pop acc
mov @R0,A
MOV A,R4
PUSH acc
MOV A,R3 ;将返回地址压入堆栈
PUSH ACC
MOV A,R2
PUSH ACC
RET
;(16) 标号: FTOD 功能:格式化浮点数转换成双字节定点数
;入口条件:格式化浮点操作数在[R0]中。
;出口信息:OV=1时溢出,OV=0时转换成功:定点数的绝对值在[R0]中(双字节),数符
;在位1FH中,F0=1 时为整数,CY=1时为一字节整数一字节小数,否则为纯小数。
FTOD: LCALL MVR0 ;;将[R0]传送到第一工作区
MOV A,R2
JZ FTD4 ;;阶码为零,纯小数
JB ACC.7,FTD4;;阶码为负,纯小数
SETB C
SUBB A,#10H
JC FTD1
SETB OV ;;阶码大于16,溢出
RET
FTD1: SETB C
MOV A,R2
SUBB A,#8 ;;阶码大于8否?
JC FTD3
FTD2: MOV B,#10H ;;阶码大于8,按双字节整数转换
LCALL FTD8
SETB F0 ;;设立双字节整数标志
CLR C
CLR OV
RET
FTD3: MOV B,#8 ;;按一字节整数一字节小数转换
LCALL FTD8
SETB C ;;设立一字节整数一字节小数标志
CLR F0
CLR OV
RET
FTD4: MOV B,#0 ;;按纯小数转换
LCALL FTD8
CLR OV ;;设立纯小数标志
CLR F0
CLR C
RET
FTD8: MOV A,R2 ;;按规定的整数位数进行右规
CJNE A,B,FTD9
MOV A,R3 ;;将双字节结果传送到[R0]中
MOV @R0,A
INC R0
MOV A,R4
MOV @R0,A
inc r0
MOV A,R5
MOV @R0,A
DEC R0
dec r0
RET
FTD9: CLR C
LCALL RR1 ;右规一次
SJMP FTD8

        END

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-7-8 07:43:22 | 显示全部楼层
汇编的,注释也很多,很强。

C是不错的选择啊。

出0入0汤圆

发表于 2011-7-8 08:34:51 | 显示全部楼层
顶楼主~

看见周航慈的函数库文件

出0入0汤圆

发表于 2011-7-8 09:07:58 | 显示全部楼层
LZ功力深厚啊

出0入0汤圆

 楼主| 发表于 2011-7-8 09:24:23 | 显示全部楼层
C是不错的选择啊---------韩国网站上有一个制作是用C语言的,不过缺H文件

出0入0汤圆

发表于 2011-7-8 09:29:41 | 显示全部楼层
浮点数转换到BCD码会导致精度不够.
计算器应该使用BCD浮点数算法

出0入0汤圆

 楼主| 发表于 2011-7-8 09:40:34 | 显示全部楼层
看见周航慈的函数库文件------------------它是”MCS-51四字节浮点库及其使用”(ht tp:/ /www.dpj.com.cn)。

出0入0汤圆

发表于 2011-7-8 09:41:34 | 显示全部楼层
功力很深;

出0入0汤圆

 楼主| 发表于 2011-7-8 09:52:51 | 显示全部楼层
浮点数转换到BCD码会导致精度不够.------------确实有点误差

出0入0汤圆

发表于 2011-7-8 10:20:30 | 显示全部楼层
汇编的,强!

出0入0汤圆

发表于 2011-7-8 11:14:55 | 显示全部楼层
强悍!

出0入0汤圆

发表于 2011-7-8 11:33:06 | 显示全部楼层
MARK,学习了。

出0入0汤圆

发表于 2011-7-8 22:59:24 | 显示全部楼层
一图抵万言

出0入0汤圆

发表于 2011-7-9 23:26:02 | 显示全部楼层
长见识了,楼主好样的》》

出0入0汤圆

 楼主| 发表于 2011-7-10 16:39:51 | 显示全部楼层
洞洞板图片:


图1 (原文件名:S1052083.JPG)


图2 (原文件名:S1052084.JPG)

出0入0汤圆

 楼主| 发表于 2011-7-10 19:32:24 | 显示全部楼层
上图

计算器电原理图ourdev_656493WTEJKK.rar(文件大小:7K) (原文件名:89c51计算器原理图20110710.rar)

出0入0汤圆

发表于 2011-7-10 19:43:35 | 显示全部楼层
顶汇编

出0入0汤圆

发表于 2011-7-10 20:09:13 | 显示全部楼层
顶汇编牛人啊

出0入0汤圆

发表于 2011-7-10 20:33:30 | 显示全部楼层
哇,汇编哥,不错,不太好读哦

出0入0汤圆

发表于 2011-7-10 22:12:35 | 显示全部楼层
ding

出0入0汤圆

 楼主| 发表于 2011-7-12 07:57:38 | 显示全部楼层
图片板上LS04没有用上。

出0入0汤圆

 楼主| 发表于 2011-7-12 08:18:03 | 显示全部楼层
上一个外国DIY网站,N多内容:


http://www.sample.co.kr/clocko/secosc.htm


国外的CALC (原文件名:secaltt.jpg)

出0入0汤圆

发表于 2011-7-30 20:37:16 | 显示全部楼层
谢谢楼主分享,…………

出0入0汤圆

发表于 2013-7-14 21:41:47 | 显示全部楼层
henhao
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 12:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表