51单片机实现的简易计算器(4)

2018-12-23 23:43

INC R1 ; 指向尾数第一个字节

; 创建尾数

; R0 指向了尾数第一个数字

; 逐个读取只到读满4个数字或者输入数据用完(DCOUNT -> 0)

MANTISSA: ; BYTE2USAGE

CLR BYTE2 ; 指示是否已经设置尾数中的第二个字节 ; 因为可能在只有一位或者二位尾数的情况下, ; 尾数中的字节2没有设置,此时必须显示将其设为0 MAKEMAN: ; MAKE MANTISSA

; 2字节的RAWIN对应于1个字节的BCD形式 ; BCD高位:第一个数字 MOV A, @R0 ; 取出 SWAP A ; 放到高字节 MOV @R1, A ; 存放

; DCOUNT 等在子程序 UPDATEM 里更新 ACALL UPDATE_MS ; UPDATE MANTISSA STATE ; BCD低位:第二个数字

MOV B, @R1 ; 取回设置了高字节的BCD MOV A, @R0 ; 取输入数字

ORL A, B ; 将原来的数和现在的数结合为BCD码 MOV @R1, A

ACALL UPDATE_MS ; 更新状态,判断是否结束

; 如果没有结束,开始一个新的字节 ; 此时至少是第二个字节,设置 BYTE2 SETB BYTE2

; 将所有的的输入数据都转换为BCD码。

; 虽然只有前4个字节(对应2字节BCD码)有效 SJMP MAKEMAN

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

UPDATE_MS: ; UPDATE MANTISSA STATE INC R0 DEC DCOUNT MOV A, DCOUNT JZ VALDONE ; 数字用完 RET VALDONE:

; 从UPDATEM子程序中跳出,首先跳过堆栈前面两个字节 POP ACC POP ACC

JB BYTE2, VALDONE_RET ; 第二个字节已经写入,可以返回 ; 尾数第二个字节没有写过,说明还需要将末尾字节填0 ; 例如,0.009,尾数为 90H XXH,第2个字节未设置 MOV A, R4 ; 取目的地址 MOV R1, A

INC R1 ; 指向第3个字节,第2个字节 INC R1 ; 不可能为零,否则整个数为0 MOV @R1, #00H VALDONE_RET: ; FINALIZE 操作 LJMP MAKENUM_DONE

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

; 计算小数点后0的个数 PUREZERO:

INC R2 ; 0个数增加

; INC R1 ; 指向下一个数据 ; CMT. 07.25 ; DEC DCOUNT ; DEL: 07.25 MOV A, DCOUNT

JZ TOVALZERO ; 如果在计算零的过程中数据用完,则这是个零 SJMP COUNTZERO ; 继续计数 ; ----------------------------------- TOVALZERO: LJMP VALZERO

; ----------------------------------- MAKENUM_DONE:

POP DCOUNT ; 恢复 DCOUNT MOV A, R4

; 进行BCD到二进制浮点数的转换

; 使用寄存器工作组10 -> OBSOLETED. 07.25 SETB RS1 CLR RS0

MOV R0, A ; R0指向刚刚创建的BCD浮点数 LCALL BTOF ; BCD TO FLOAT ; 恢复寄存器工作组01 CLR RS1 SETB RS0

RET ; MAKENUM 完成

; =======================================================

CALCULATE: ; NOTEE!!!

; 操作数在NUM1, NUM2,格式为MAKENUM的结果,即二进制的浮点数 ; 可以直接对其进行浮点程序库的调用 ; REGISTER GROUP 10 SETB RS1 CLR RS0

; 操作数: MOV R0, #NUM1 MOV R1, #NUM2

; 根据计算器的状态进行加减乘除的调用 ; 操作符保存在 STAT 的第5第4位 ;54: OPERATOR ; 00: ADD (0) ; 01: SUB (1) ; 10: MUL (2) ; 11: DIV (3) MOV A, STAT

ANL A, #30H ; 仅保留5,4两位 SWAP A ; 切换到低位用于查表 JZ CALC_ADD ; 0表示加 DEC A

JZ CALC_SUB ; 减1后为零,说明原来是1,表示减 DEC A

JZ CALC_MUL ; 乘法 DEC A

JZ CALC_DIV ; 除法 ; ----------- CALC_DONE:

; 如果 OV 为1,则计算结果有误,设置错误位STAT.7 ; 显示的时候如果STAT.7为1,则显示错误字符 E JNB OV, CALC_OK ; OV为1,设置 STAT.7 SETB STAT.7 CALC_OK: RET ; -------- CALC_ADD: LCALL FADD SJMP CALC_DONE CALC_SUB: LCALL FSUB SJMP CALC_DONE

CALC_MUL: LCALL FMUL SJMP CALC_DONE CALC_DIV: LCALL FDIV SJMP CALC_DONE

; ======================================================= RES2RAW: ; NOTEE!!!

; 运算结束后,NUM1中存放的是3字节二进制浮点数格式的结果, ; 将其转换为RAWIN形式存放于RAWIN位置,供显示程序使用

; 首先将结果转换为 BCD 的浮点数,保存于一个临时位置TEMP

MOV R0, #NUM1 ; 初始化要转换的数字 MOV R1, #TEMP ; 暂存地址

MOV R2, #03H ; 移动3个字节, R2仅使用于R2R_COPY3 R2R_COPY3: ; 将NUM1复制到 TEMP MOV A, @R0 MOV @R1, A INC R0 INC R1

DJNZ R2, R2R_COPY3

MOV R0, #TEMP ; 将这个二进制浮点数转换为BCD格式浮点数 ; 注意:NUM1中数字不可转换,因为之后还要在计算中使用

; 寄存器工作组 10 SETB RS1 CLR RS0

LCALL FTOB ; FLOAT TO BCD

; 恢复使用寄存器组01 CLR RS1 SETB RS0 ; 初始化

MOV DCOUNT, #00H ; 数字个数计数(此计数包括减号和小数点) ; 判断是否为零(即2,3字节均为00H) MOV R0, #TEMP ; 间接取址寄存器

INC R0 ; 字节2 MOV A, @R0

JZ R2R_B2_ZERO ; 为零,继续检查第三字节是否为零

SJMP R2R_NORMAL ; 开始正常处理

R2R_B2_ZERO: ; RES2RAW, BYTE 2, ZERO INC R0 ; 第三个字节 MOV A, @R0 JZ R2R_VAL_ZERO

SJMP R2R_NORMAL ; 开始正常处理 R2R_VAL_ZERO: ; R2R, VALUE, ZERO

MOV DCOUNT, #00H ; DCOUNT 为零表示结果为零 RET

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

R2R_NORMAL: ; 非零情况 ; 寄存器使用: ; R0 源指针 ; R1 目的指针 ; R2 临时 ; R3 临时 ; R4 ; R5

; R6 指数迭代器 ; R7 循环计数器

MOV R0, #TEMP ; 源指针 MOV R1, #RAWIN ; 目的指针

MOV A, TEMP ; 取第一个字节,即指数 JNB ACC.7, R2R_POS ; 最高位为0,正数

; 否则为负数,应该先放置一个'-' ; '-' 用 #0BH 表示 MOV @R1, #0BH INC R1 ; 下一个位置

INC DCOUNT ; DCOUNT指示整个字符串长度

R2R_POS: ; RES2RAW, POSITIVE: 正数 MOV C, ACC.6 ; 指数的符号位是第7位

MOV ACC.7, C ; 设置A的最高位为A的第6位,即指数的符号位 JZ R2R_ZERO_E ; 指数为零,数字形式为 0.XXXX

; NOTE: JUMP OUT OF RANGE?? JNB ACC.7, R2R_POS_E ; 指数为正


51单片机实现的简易计算器(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:小学语文二年级上册(人教版)期中测试题

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: