可实现加减乘除,除法可显示小数点后一位,实现连加减运算
单片机源程序如下:
DATA SEGMENT
X DB ?,?,?,? ;存放数据的每一位
X1 DW ? ;存放第一个数据值
X2 DW ? ;存放第二个数据值
Y DW ? ;存放运算结果
S DB ? ;存放运算符号值
E DB ? ;按下等号键标记
CC DB ? ;存放运算数据位数
H DB 0 ;存放按键行号
L DB 0 ;存放按键列号
DISCODE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H ;段码表
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV AL,90H ;设置为A口输入,B口输出,C口输出
OUT 46H,AL
MOV DI,OFFSET X+3 ;DI指向X的高位
KKK: CALL KEY ;扫描按键
JMP KKK
;以下为按键扫描子程序,程序返回后,在变量H和L中存放当前按键的行列号
KEY PROC
CHECK: CALL DISP ;等待按键按下的同时进行显示
MOV AL,0F0H ;所有行输出低电平
OUT 44H,AL
IN AL,40H
CMP AL,0FFH ;读列值
JZ CHECK ;若都为高电平则无键按下,等待
MOV CX,50
LOOP $ ;延时消抖
IN AL,DX ;重读列值
CMP AL,0FFH
JZ CHECK ;无键按下一直等待
MOV H,0 ;有键按下,先把行列号变量清0
MOV L,0
MOV BL,01H
MOV BH,0FEH ;扫描法读键值:从第一行开始测试,即PC0输出低电平
NEXT: MOV AL,BH
OUT 44H,AL
NEXTH: IN AL,40H ;读列值,判断是第几列有键按下
TEST AL,BL ;从第一列开始判断
JZ WAIT0
ROL BL,1
CMP BL,10H ;当前行状态下没有任何列有键按下,则转为对下一行的测试
JZ NEXTL
INC H ;每判断一列,列号加1
JMP NEXTH ;再对下一列进行判断
NEXTL: MOV H,0
MOV BL,01H
ROL BH,1 ;对下一行测试,让下一个PC口输出低电平
CMP BH,0EFH
JZ EXIT
INC L
JMP NEXT
WAIT0: IN AL,40H ;若有键按下,则等该按键松开后再计算键值
CMP AL,0FFH
JNZ WAIT0
MOV CX,50
LOOP $ ;延时消抖
IN AL,40H
CMP AL,0FFH
JNZ WAIT0
CALL KEYVALUE ;调计算键值子程序
EXIT: RET
KEY ENDP
;以下为计算键值子程序,通过行列号计算键值(键值=列号*4+行号)
;键值存放在DL寄存器中
KEYVALUE PROC
MOV DL,L
MOV DH,H
SHL DL,1
SHL DL,1 ;列号乘4
ADD DL,DH
CMP DL,9 ;按下的是数字键
JNG NUM_CALL
CMP DL,14
JL CONT_CALL ;按下的是运算键
CMP DL,14
JZ OUTP_CALL ;按下的是等于键
CMP DL,15
JZ CLR_CALL ;按下的是清除键
NUM_CALL: CALL NUMBER ;调数字键处理子程序
JMP EXIT1
CONT_CALL: MOV S,DL ;存放运算键的键值
MOV E,0
CALL COUNT ;调运算键处理子程序,计算第一个加数
JMP EXIT1
OUTP_CALL: CALL OUTP ;调等号键处理子程序
JMP EXIT1
CLR_CALL: CALL CLEAR ;调清除键处理子程序
EXIT1: RET
KEYVALUE ENDP
;以下为清除键处理子程序,按下清除键后,X变量全部清0
CLEAR PROC
MOV X[3],0
MOV X[2],0
MOV X[1],0
MOV X[0],0
CALL BITP
RET
CLEAR ENDP
;以下为等号键处理子程序,该子程序负责将第二个运算数据的数值计算出来存入X2变量
;并根据运算符号,调用相应的运算子程序
OUTP PROC
PUSH AX
PUSH DX
PUSH BX
INC E
CALL COUNT ;调运算键处理子程序,计算第二个运算数据
CMP S,10
JZ ADD_CALL ;运算符为加号,则调用加法子程序
CMP S,11
JZ SUB_CALL ;运算符为减号,则调用减法子程序
CMP S,12
JZ MUL_CALL ;运算符为乘号,则调用乘法子程序
CMP S,13
CALL DIVP ;运算符为除号,则调用除法子程序
JMP STORE1
ADD_CALL: CALL ADDP
JMP STORE1
SUB_CALL: CALL SUBP
JMP STORE1
MUL_CALL: CALL MULP
STORE1: MOV AX,Y ;以下程序将各运算子程序返回的运算结果,按位分解,送入X变量
MOV DX,0
MOV BX,1000
DIV BX
MOV X[0], AL
MOV AX,DX
MOV BL,100
DIV BL
MOV X[1],AL
MOV AL,AH
MOV AH,0
MOV BL,10
DIV BL
MOV X[2],AL
MOV X[3],AH
POP BX
POP DX
POP AX
RET
OUTP ENDP
;以下为运算键处理子程序,该程序将第一个运算数据的数值计算出来并存入X1变量
;或者将第二个运算数据的数值计算出来并存入X2变量
;将运算符的值存入S变量
COUNT PROC
PUSH AX
PUSH BX
PUSH DX
MOV DX,0
CALL BITP ;测试X中的数据是多少位
CMP CC,4 ;输入的数据是4位数 ?
JZ C4
CMP CC,3 ;输入的数据是3位数 ?
JZ C3
CMP CC,2 ;输入的数据是2位数 ?
JZ C2
JMP C1 ;输入的数据是1位数 ?
C4: MOV AX,0
MOV AL,X[0]
MOV BX,1000
MUL BX
MOV DX,AX
C3: MOV AL,X[1]
MOV BL,100
MUL BL
ADD DX,AX
C2: MOV AL,X[2]
MOV BL,10
MUL BL
ADD DX,AX
C1: MOV AL,X[3]
MOV AH,0
ADD DX,AX
CMP E,1
JNZ X1_S
MOV X2,DX ;按下的是等号,则将第二个运算数据的值存入X2变量
JMP EXIT3
X1_S: MOV X1,DX ;按下的是运算符号,则将第一个运算数据的值存X1变量
MOV X[3],0 ;清空X变量
MOV X[2],0
MOV X[1],0
MOV X[0],0
EXIT3: POP DX
POP BX
POP AX
RET
COUNT ENDP
;以下为数字键处理子程序
;该程序,将输入的数据按位存放在X变量中,并由CC记录数据的位数
NUMBER PROC
CMP E,1
JNZ CONTINUE
MOV E,0
CALL CLEAR
CONTINUE: CMP CC,0 ;目前数据为0位,即没有数据,则转到SSS
JZ SSS
;若已有数据,以下程序将X左移8位。
;例如:先输入“1”,当再输入2时,
;先要将“1”从个位移到十位,然后再将“2”存放到个位
PUSH AX
PUSH DX
MOV AL,X[3]
MOV AH,X[2]
MOV DL,X[1]
MOV DH,X[0]
MOV CX,8
LL: SHL AX, 1
RCL DX,1
LOOP LL
MOV X[3],AL
MOV X[2],AH
MOV X[1],DL
MOV X[0],DH
POP DX
POP AX
SSS: MOV [DI],DL ;将当前键入的数据存放到X的最低位
INC CC ;数据位数加1
CMP CC,4 ;判断数据位数
JNG EXIT2
MOV CC,0 ;如果数据超过4位,重新从最低位开始存放
MOV X[2],0
MOV X[1],0
MOV X[0],0
EXIT2: CALL DISP ;调显示子程序,显示输入的数据
RET
NUMBER ENDP
;加法子程序
ADDP PROC
PUSH AX
MOV AX,X1
ADD AX,X2
MOV Y,AX
POP AX
RET
ADDP ENDP
;减法子程序
SUBP PROC
PUSH AX
MOV AX,X1
SUB AX,X2
MOV Y,AX
POP AX
RET
SUBP ENDP
;乘法子程序
MULP PROC
PUSH AX
PUSH DX
MOV AX,X1
MOV DX,X2
MUL DX
MOV Y,AX
POP DX
POP AX
RET
MULP ENDP
;除法子程序
DIVP PROC
PUSH AX
PUSH BX
PUSH DX
MOV DX,0
MOV AX,X1
MOV BX,X2
DIV BX
MOV Y,AX
POP DX
POP BX
POP AX
RET
DIVP ENDP
;显示子程序 ,将X中的数值按位显示出来
DISP PROC
PUSH BX
PUSH AX
MOV BH,0
LEA SI,DISCODE
CALL BITP ;测试X位数
CMP CC,4
JZ QIAN
CMP CC,3
JZ BAI
CMP CC,2
JZ SHI
CMP CC,1
JMP G
JMP NONE
QIAN: MOV AH,11100000B ;从第4位开始显示
MOV AL,AH
OUT 44H,AL
MOV BL,X[0]
MOV AL,[SI+BX]
OUT 42H,AL
CALL DELY
MOV AL,0
OUT 42H,AL
BAI: MOV AH,11010000B ;从第3位开始显示
MOV AL,AH
OUT 44H,AL
MOV BL,X[1]
MOV AL,[SI+BX]
OUT 42H,AL
CALL DELY
MOV AL,0
OUT 42H,AL
SHI: MOV AH,10110000B ;从第2位开始显示
MOV AL,AH
OUT 44H,AL
MOV BL,X[2]
MOV AL,[SI+BX]
OUT 42H,AL
CALL DELY
MOV AL,0
OUT 42H,AL
G: MOV AH,01110000B ;从第1位开始显示
MOV AL,AH
OUT 44H,AL
MOV BL,X[3]
MOV AL,[SI+BX]
OUT 42H,AL
CALL DELY
JMP EXIT4
NONE: MOV AL,0 ;X中没有数据,不显示
OUT 42H,AL
EXIT4: POP AX
POP BX
RET
DISP ENDP
;分析数据位数子程序
BITP PROC
CMP X[0],0 ;如果X[0]不为0,则数据为4位数
JNZ FOURBIT
CMP X[1],0 ;如果X[1]不为0,则数据为3位数
JNZ THREEBIT
CMP X[2],0 ;如果X[2]不为0,则数据为2位数
JNZ TOWBIT
CMP X[3],0 ;如果X[3]不为0,则数据为1位数
JNZ ONEBIT
JMP ZER0BIT ;否则,没有数据
FOURBIT: MOV CC,4
JMP EXIT5
THREEBIT: MOV CC,3
JMP EXIT5
TOWBIT: MOV CC,2
JMP EXIT5
ONEBIT: MOV CC,1
JMP EXIT5
ZER0BIT: MOV CC,0
EXIT5: RET
BITP ENDP
;延时子程序
DELY PROC
PUSH CX
MOV CX,100
LOOP $
POP CX
RET
DELY ENDP
CODE ENDS
END START
全部资料51hei下载地址:
计算器.rar
(24.5 KB, 下载次数: 74)
|