⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 计算器.txt

📁 在51单片机上实现4X4键盘控制的简易计算器功能.能实现加减乘除功能
💻 TXT
📖 第 1 页 / 共 4 页
字号:
  KEY4: SETB P1.0
        MOV DPTR,#TBK
        MOV A,R7
        MOVC A,@A+DPTR
        MOV  R7,A
        SJMP KEY6
  KEY5: MOV A,#0F0H
        NOP
  KEY6: NOP
        RET 
;---
TBK:
; 键盘布局
DB 07H, 08H, 09H, 10H ; 7 8 9 +
DB 04H, 05H, 06H, 20H ; 4 5 6 -
DB 01H, 02H, 03H, 30H ; 1 2 3 *
DB 00H, 0FFH, 80H, 40H ; 0 . = /

;**************************************
;显示程序
;**************************************
DISPLAY:
     MOV DPTR, #DISPTAB
     MOV R0, #RAWIN
     MOV TEMP1, DCOUNT
     ; CLEAR THE SCREEN
     MOV COM, #01H
     LCALL PR1
     
     MOV A, DCOUNT
     JZ DISP_ZERO
     
     JB STAT.7, DISP_ERR
DISP_NORMAL:
MOV A, @R0
INC R0
INC A
JZ DISP_DP
DEC A
DISP_LOOKUP:
MOVC A, @A+DPTR
MOV DAT, A
LCALL PR2
LCALL DELAY
DJNZ TEMP1, DISP_NORMAL
SJMP DISP_DONE
; -----------
DISP_ZERO:
MOV A, #00H ; '0'
MOV TEMP1, #01H
SJMP DISP_LOOKUP

; --------------
DISP_DP: ; DISPLAY, DECIMAL POINT
MOV A, #0AH
SJMP DISP_LOOKUP
; -----------
DISP_ERR:
     MOV A, #0CH ; 'E'
     MOVC A, @A+DPTR
     MOV DAT, A
     LCALL PR2
     LCALL DELAY
     SJMP DISP_DONE
; ----------------
DISP_DONE:
RET
;=================
DISPTAB:
DB 30H,31H,32H,33H,34H,35H,36H,37H, 38H, 39H
DB 2EH, 2DH, 45H ; '.', '-', 'E'    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

;;***************************************
;; LCD 初始化程序
;;***************************************
LCDINIT:MOV   A,#30H
        MOV   DPTR,#CW_ADD
        MOV   R2,#03H
LCDINT1:MOVX  @DPTR,A
        LCALL DELAY
        DJNZ  R2,LCDINT1
        MOV   COM,#38H
        LCALL PR1
        MOV   COM,#01H
        LCALL PR1
        MOV   COM,#06H     ;设置输入方式
        LCALL PR1
        MOV   COM,#0FH      
        LCALL PR1
        
        RET


;********************************
;读BF和AC值
;********************************


PR0: PUSH  DPH
     PUSH  DPL
     PUSH  ACC
     MOV   DPTR,#CR_ADD
     MOVX  A,@DPTR
     MOV   COM,A
     POP   ACC
     POP   DPL
     POP   DPH
     RET
;********************************
;写指令代码字程序
;********************************
     
PR1: PUSH  DPH
     PUSH  DPL
     PUSH  ACC
     MOV   DPTR,#CR_ADD       
PR11:MOVX  A,@DPTR
     JB    ACC.7,PR11
     MOV   A,COM
     MOV   DPTR,#CW_ADD
     MOVX  @DPTR,A
     POP   ACC
     POP   DPL
     POP   DPH
     RET
;********************************
;写显示数据子程序
;******************************** 
PR2: PUSH   DPH
     PUSH   DPL
     PUSH   ACC
     MOV    DPTR,#CR_ADD
PR21:MOVX   A,@DPTR
     JB     ACC.7,PR21
     MOV    A,DAT
     MOV    DPTR,#DW_ADD
     MOVX   @DPTR,A
     POP    ACC
     POP    DPL
     POP    DPH
     RET       
;********************************
;读显示数据子程序
;******************************** 
PR3: PUSH   DPH
     PUSH   DPL
     PUSH   ACC
     MOV    DPTR,#CR_ADD
PR31:MOVX   A,@DPTR
     JB     ACC.7,PR31
     MOV    DPTR,#DR_ADD
     MOVX   A,@DPTR
     MOV    DAT,A
     POP    ACC
     POP    DPL
     POP    DPH
     RET
     
;*****************************************
;  DELAY
;*****************************************
DELAY:  MOV   R6,#02H
        MOV   R7,#02H
DELAY1: NOP
        DJNZ  R7,DELAY1
        DJNZ  R6,DELAY1
        RET 


; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FLOATLIB          浮点程序库
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

;(1) 标号: FSDT 功能:浮点数格式化 

;入口条件:待格式化浮点操作数在[R0]中。 
;出口信息:已格式化浮点操作数仍在[R0]中。 
;影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节 
FSDT: LCALL MVR0 ; 将待格式化操作数传送到第一工作区中 
LCALL RLN ; 通过左规完成格式化 
LJMP MOV0 ; 将已格式化浮点操作数传回到[R0]中 

;(2) 标号: FADD 功能:浮点数加法 

;入口条件:被加数在[R0]中,加数在[R1]中。 
;出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。 
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 6字节 
FADD: CLR F0 ; 设立加法标志 
SJMP AS ; 计算代数和 

;(3) 标号: FSUB 功能:浮点数减法 

;入口条件:被减数在[R0]中,减数在[R1]中。 
;出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。 
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节 
FSUB: SETB F0 ; 设立减法标志 
AS: LCALL MVR1 ; 计算代数和。先将[R1]传送到第二工作区 
MOV C,F0 ; 用加减标志来校正第二操作数的有效符号 
RRC A 
XRL A,@R1 
MOV C,ACC.7 
ASN: MOV 1EH,C ; 将第二操作数的有效符号存入位1EH中 
XRL A,@R0 ; 与第一操作数的符号比较 
RLC A 
MOV F0,C ; 保存比较结果 
LCALL MVR0 ; 将[R0]传送到第一工作区中 
LCALL AS1 ; 在工作寄存器中完成代数运算 
MOV0: INC R0 ; 将结果传回到[R0]中的子程序入口 
INC 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 ; 将[R0]传送到第一工作区中的子程序 
MOV C,ACC.7 ; 将数符保存在位1FH中 
MOV 1FH,C 
MOV C,ACC.6 ; 将阶码扩充为8bit补码 
MOV ACC.7,C 
MOV R2,A ; 存放在R2中 
INC R0 
MOV A,@R0 ; 将尾数高字节存放在R3中 
MOV R3,A 
INC R0 
MOV A,@R0 ; 将尾数低字节存放在R4中 
MOV R4,A 
DEC R0 ; 恢复数据指针 
DEC R0 
RET 
MVR1: MOV A,@R1 ; 将[R1]传送到第二工作区中的子程序 
MOV C,ACC.7 ; 将数符保存在位1EH中 
MOV 1EH,C 
MOV C,ACC.6 ; 将阶码扩充为8bit补码 
MOV ACC.7,C 
MOV R5,A ; 存放在R5中 
INC R1 
MOV A,@R1 ; 将尾数高字节存放在R6中 
MOV R6,A 
INC R1 
MOV A,@R1 ; 将尾数低字节存放在R7中 
MOV R7,A 
DEC R1 ; 恢复数据指针 
DEC R1 
RET 
AS1: MOV A,R6 ; 读取第二操作数尾数高字节 
ORL A,R7 
JZ AS2 ; 第二操作数为零,不必运算 
MOV A,R3 ; 读取第一操作数尾数高字节 
ORL A,R4 
JNZ EQ1 
MOV A,R6 ; 第一操作数为零,结果以第二操作数为准 
MOV R3,A 
MOV A,R7 
MOV R4,A 
MOV A,R5 
MOV R2,A 
MOV C,1EH 
MOV 1FH,C 
AS2: RET 
EQ1: MOV A,R2 ; 对阶,比较两个操作数的阶码 
XRL A,R5 
JZ AS4 ; 阶码相同,对阶结束 
JB ACC.7,EQ3; 阶符互异 
MOV A,R2 ; 阶符相同,比较大小 
CLR C 
SUBB A,R5 
JC EQ4 
EQ2: CLR C ; 第二操作数右规一次 
MOV A,R6 ; 尾数缩小一半 
RRC A 
MOV R6,A 
MOV A,R7 
RRC A 
MOV R7,A 
INC R5 ; 阶码加一 
ORL A,R6 ; 尾数为零否? 
JNZ EQ1 ; 尾数不为零,继续对阶 
MOV A,R2 ; 尾数为零,提前结束对阶 
MOV R5,A 
SJMP AS4 
EQ3: MOV A,R2 ; 判断第一操作数阶符 
JNB ACC.7,EQ2; 如为正,右规第二操作数 
EQ4: CLR C 
LCALL RR1 ; 第一操作数右规一次 
ORL A,R3 ; 尾数为零否? 
JNZ EQ1 ; 不为零,继续对阶 
MOV A,R5 ; 尾数为零,提前结束对阶 
MOV R2,A 
AS4: JB F0,AS5 ; 尾数加减判断 
MOV A,R4 ; 尾数相加 
ADD A,R7 
MOV R4,A 
MOV A,R3 
ADDC A,R6 
MOV R3,A 
JNC AS2 
LJMP RR1 ; 有进位,右规一次 
AS5: CLR C ; 比较绝对值大小 
MOV A,R4 
SUBB A,R7 
MOV B,A 
MOV A,R3 
SUBB A,R6 
JC AS6 
MOV R4,B ; 第一尾数减第二尾数 
MOV R3,A 
LJMP RLN ; 结果规格化 
AS6: CPL 1FH ; 结果的符号与第一操作数相反 
CLR C ; 结果的绝对值为第二尾数减第一尾数 
MOV A,R7 
SUBB A,R4 
MOV R4,A 
MOV A,R6 
SUBB A,R3 
MOV R3,A 
RLN: MOV A,R3 ; 浮点数规格化 
ORL A,R4 ; 尾数为零否? 
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,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 R2,#0C1H 
RL1E: CLR OV 
RET 
RR1: MOV A,R3 ; 第一操作数右规一次 
RRC A ; 尾数缩小一半 
MOV R3,A 
MOV A,R4 
RRC A 
MOV R4,A 
INC R2 ; 阶码加一 
CLR OV ; 清溢出标志 
CJNE R2,#40H,RR1E; 阶码上溢否? 
MOV R2,#3FH ; 阶码溢出 
SETB OV 
RR1E: RET

;(4) 标号: FMUL 功能:浮点数乘法 

;入口条件:被乘数在[R0]中,乘数在[R1]中。 
;出口信息:OV=0时,积仍在[R0]中,OV=1时,溢出。 
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节 
FMUL: LCALL MVR0 ; 将[R0]传送到第一工作区中 
MOV A,@R0 
XRL A,@R1 ; 比较两个操作数的符号 
RLC A 
MOV 1FH,C ; 保存积的符号 
LCALL MUL0 ; 计算积的绝对值 
LJMP MOV0 ; 将结果传回到[R0]中 
MUL0: LCALL MVR1 ; 将[R1]传送到第二工作区中 
MUL1: MOV A,R3 ; 第一尾数为零否? 
ORL A,R4 
JZ MUL6 
MOV A,R6 ; 第二尾数为零否? 
ORL A,R7 
JZ MUL5 
MOV A,R7 ; 计算R3R4×R6R7-→R3R4 
MOV B,R4 
MUL AB 
MOV A,B 
XCH A,R7 
MOV B,R3 
MUL AB 
ADD A,R7 
MOV R7,A 
CLR A 
ADDC A,B 
XCH A,R4 
MOV B,R6 
MUL AB 
ADD A,R7 
MOV R7,A 
MOV A,B 
ADDC A,R4 
MOV R4,A 
CLR A 
RLC A 
XCH A,R3 
MOV B,R6 
MUL AB 
ADD A,R4 
MOV R4,A 
MOV A,B 
ADDC A,R3 
MOV R3,A 
JB ACC.7,MUL2; 积为规格化数否? 
MOV A,R7 ; 左规一次 
RLC A 
MOV R7,A 
LCALL RL1 
MUL2: MOV A,R7 
JNB ACC.7,MUL3 
INC R4 
MOV A,R4 
JNZ MUL3 
INC R3 
MOV A,R3 
JNZ MUL3 
MOV R3,#80H 
INC R2 
MUL3: MOV A,R2 ; 求积的阶码 
ADD A,R5 
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 R3,A 
MOV R4,A 
MOV R2,#41H 
MUL6: CLR OV 
RET 

;(5) 标号: FDIV 功能:浮点数除法 

;入口条件:被除数在[R0]中,除数在[R1]中。 
;出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。 
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 5字节 
FDIV: INC R0 
MOV A,@R0 
INC R0 
ORL A,@R0 
DEC R0 
DEC R0 
JNZ DIV1 
MOV @R0,#41H; 被除数为零,不必运算 
CLR OV 
RET 
DIV1: INC R1 
MOV A,@R1 
INC R1 
ORL A,@R1 
DEC R1 
DEC R1 
JNZ DIV2 
SETB OV ; 除数为零,溢出 
RET 
DIV2: LCALL MVR0 ; 将[R0]传送到第一工作区中 
MOV A,@R0 
XRL A,@R1 ; 比较两个操作数的符号 
RLC A 
MOV 1FH,C ; 保存结果的符号 
LCALL MVR1 ; 将[R1]传送到第二工作区中 
LCALL DIV3 ; 调用工作区浮点除法 
LJMP MOV0 ; 回传结果 
DIV3: CLR C ; 比较尾数的大小 
MOV A,R4 
SUBB A,R7 
MOV A,R3 
SUBB A,R6 
JC DIV4 
LCALL RR1 ; 被除数右规一次 
SJMP DIV3 
DIV4: CLR A ; 借用R0R1R2作工作寄存器 
XCH A,R0 ; 清零并保护之 
PUSH ACC 
CLR A 
XCH A,R1 
PUSH ACC 
MOV A,R2 
PUSH ACC 
MOV B,#10H ; 除法运算,R3R4/R6R7-→R0R1 
DIV5: CLR C 
MOV A,R1 
RLC A 
MOV R1,A 
MOV A,R0 
RLC A 
MOV R0,A 
MOV A,R4 
RLC A 
MOV R4,A 
XCH A,R3 
RLC A 
XCH A,R3 
MOV F0,C 
CLR C 
SUBB A,R7 
MOV R2,A 
MOV A,R3 
SUBB A,R6 
ANL C,/F0 
JC DIV6 
MOV R3,A 
MOV A,R2 
MOV R4,A 
INC R1 
DIV6: DJNZ B,DIV5 
MOV A,R6 ; 四舍五入 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -