求助:关于80C51单片机简易计算器设计的程序,要求是汇编语言。谢谢哈

这是我的原理图,供参考,想实现两位数的加减乘除,感激不尽感激不尽。

ORG 0000H
START:MOV 78H,#0 ;初始化:78H放0的段码,其余放熄灭码
MOV 79H,#10
MOV 7AH,#10
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
MOV R5, #0 ;R5是按键次数,初始置0
MOV 30H,#0 ;30H是功能键存放单元,置为0
MOV 40H,#0 ;40H单元初始置为0
MOV 41H,#0 ;41H单元初始置为0
LOOP:LCALL DIR
LCALL KEY
INC R5
;散转程序,判断按下的是哪个键
S1:CJNE A,#10,S2 ;不是"+"键,跳到S2
LJMP FUN ;是"+"键,跳到FUN
S2:CJNE A,#11,S3 ;不是"-"键,跳到S3
LJMP FUN ;是"-"键,跳到FUN
S3:CJNE A,#12,S4 ; 不是"*"键,跳到S4
LJMP FUN ; 是"*"键,跳到FUN
S4:CJNE A,#13,S5 ; 不是"/"键,跳到S5
LJMP FUN ; 是"/"键,跳到FUN
S5:CJNE A,#14,S6 ; 不是"="键,跳到S6
LJMP FUN ;是"="键,跳到FUN
S6:CJNE A,#15,N1 ; 不是"CL"键,跳到N1
LJMP START ; 是"CL"键,跳到START
N1:CJNE R5,#1,N2 ;判断第几次按键
LJMP D11
N2:CJNE R5,#2,N3
LJMP T2
N3:CJNE R5,#3,N4
LJMP T3
N4:CJNE R5,#4,N5
LJMP T4
N5:CJNE R5,#5,N6
LJMP T5
N6:CJNE R5,#6,START
LJMP T6

D11:MOV R4,A
MOV 78H,A ;输入值送显示个位缓存
MOV 79H,#10
MOV 7AH,#10
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
LJMP LOOP
T2:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7AH,#10
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
MOV 79H, 78H ;个位到十位
MOV 78H,R7 ;新数为个位
LJMP LOOP
T3:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
MOV 7AH,79H ;十位到百位
MOV 79H,78H ;个位到十位
MOV 78H,R7 ; 新数为个位
LJMP LOOP
T4:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7CH,#10
MOV 7DH,#10
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP
T5:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7DH,#10

MOV 7CH,7BH
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP

T6:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7DH,7CH
MOV 7CH,7BH
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP

MOV 7CH,7BH
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP

FUN:MOV 78H,#10
MOV 79H,#10
MOV 7AH,#10
MOV R0,30H ;与上次功能键交换
MOV 30H,A
MOV A,R0
CJNE A,#10,FUN1 ;判断功能键
LJMP ADDY ;"+"
FUN1:CJNE A,#11,FUN2
LJMP SUBT ;"-"
FUN2:CJNE A,#12,FUN3
LJMP MULT ;"*"
FUN3:CJNE A,#13,FUN4
LJMP DIVI ;"/"
FUN4:CJNE A,#14,FUN5 ;首次按功能键,即A=#0
LJMP EQUA ;"="
FUN5:MOV 40H,R4 ;保存第一个数
MOV R5,#0 ;按键次数清零
LJMP BCD ;将其拆为bcd码,以便后来将其显示
OF:LJMP START ;溢出处理
ADDY:MOV A,40H ;第一个数送累加器
ADD A,R4 ;第一个数加第二个数
JB CY,OF ;溢出
MOV 40H,A ;存本次结果
MOV R5,#0 ;按键次数清零
LJMP BCD
SUBT:MOV A,40H
SUBB A,R4
JB CY,OF
MOV 40H,A
MOV R5,#0
LJMP BCD
MULT:MOV A,40H
MOV B,A
MOV A,R4
MUL AB
JB OV,OF
MOV 40H,A
MOV R5,#0
LJMP BCD
DIVI:MOV A,R4
MOV B,A
MOV A,40H
DIV AB
JB OV,OF
MOV 40H,A
MOV R5,#0
LJMP BCD
EQUA:MOV R5,#0
LJMP BCD
BCD:MOV B,#10
MOV A,40H ;结果送累加器
DIV AB ;结果除10
MOV 41H,A ;暂存"商"
MOV A,B ;取个位数
MOV 78H,A ;个位数送显示缓存
MOV A,41H
JZ RETURN ;结果是一位数,返回LOOP
MOV B,#10
MOV A,41H
DIV AB
MOV 41H,A
MOV A,B
MOV 79H,A ;十位送显示缓存
MOV A,41H
JZ RETURN ;结果是二位数,返回LOOP
MOV 7AH,A ;百位数送显示缓存
RETURN:LJMP LOOP
;动态显示子程序
DIR:MOV DPTR,#TAB ; 数码管译码表首址
MOV R0,#78H ;待显缓冲区个位地址
MOV A,#0FEH ; 个位位选信号
MOV R1,A
LD1:MOV A,@R0
MOVC A,@A+DPTR ;查表
MOV P2,R1 ;共阳极管字位选择送到P2口
MOV P0,A ;字段码送P0口
LCALL DELAY1ms ;调延时1ms 子程序
INC R0 ;R0指向下一模块
MOV A,R1 ;
JNB ACC.5,LD2 ;判断是否发完6个数
RL A ;指向下一个位
MOV R1,A ;位选信号存回R3
SJMP LD1 ;跳去再显示下一个数
LD2:RET ;发完6个数就返回
TAB:DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,80H,90H,0FFH ;共阳极译码表
DELAY1ms:MOV R6,#2
LOOP1:MOV R7,#248
NOP
LOOP2:DJNZ R7,LOOP2
DJNZ R6,LOOP1
RET
KEY:LCALL KS ;调用检测按键子程序
JNZ K1 ;有键按下继续
LCALL DELAY2 ;无键按调用延时去抖
ACALL DIR ;调用动态显示
AJMP KEY ;返回继续检测按键
K1:LCALL DELAY2 ;有键按下延时去抖动
LCALL KS ;再调用检测按腱子程序
JNZ K2 ;确认有按键进行下一步
ACALL DIR ;调用动态显示
AJMP KEY ;无键按下返回继续检测
K2:MOV R2,#0EFH ;将扫描值送入R2暂存
MOV R3,#00H ;将第一列值送入R3暂存
K3:MOV P1,R2 ;将R2值送入P1口
L0:JB P1.0,L1 ;P1.0等于1跳转到L1
MOV A,#00H ;将第一行值送入ACC
AJMP LK ;跳转到键值处理程序
L1:JB P1.1,L2 ;P1.1等于1跳转到L2
MOV A,#04H ;将第二行的行值送入ACC
AJMP LK ;跳转到键值处理程序
L2:JB P1.2,L3 ;P1.2等于1跳转到L3
MOV A,#08H ;将第三行行值送入ACC
AJMP LK ;跳转到键值处理程序
L3:JB P1.3,NEXT ;P1.3等于1跳转到NEXT处
MOV A,#0CH ;将第四行行值送入ACC
LK:ADD A,R3 ;行值与列值相加后的键值送入A
PUSH ACC ;将A中的值送入堆栈暂存
K4:LCALL DELAY2 ;调用延时去抖程序
LCALL KS ;调用按键检测程序
JNZ K4 ;按键没有松开继续返回检测
POP ACC ;将堆栈值送入ACC
MOV DPTR,#KEYTAB
MOVC A,@A+DPTR
RET
NEXT:INC R3 ;列值加一
MOV A,R2 ;R2值送入A
JNB ACC.7,KEY ;扫描完至KEY处进行下一扫描
RL A ;扫描未完将值左移一位进行下一列扫描
MOV R2,A ;将ACC值送入R2暂存
AJMP K3 ;跳转到K3继续
KS:MOV P1,#0FH ;将P1口高四位置0低四位置1
MOV A,P1 ;读P1口
XRL A,#0FH ;将A中的值与A中的值相异或
RET ;子程序返回
KEYTAB:DB 1,2,3,10,4,5,6,11,7,8,9,12,15,0,14,13 ;键值表
DELAY2:MOV R6,#2H ;延时去抖动子程序
LP1:MOV R7,#0FAH
LP2:DJNZ R7,LP2
DJNZ R6,LP1
RET

END
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-09-08
结合1,2,3楼,考虑了溢出问题。花了好多时间才想出来了。
希望对你有帮助。
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:
MOV R0,#50H
MOV R7,#10
MOV R2,#00H
MOV A,#00H
LOOP:CLR C
ADD A,@R0
JNC BBB
INC R2
CLR C
BBB: INC R0
DJNZ R7,LOOP
MOV 5CH,A ;把和放5CH,不用管溢出的,和为s1
MOV 5BH,R2 ;把溢出的次数放地址5BH
MOV B,5BH ;溢出的次数给B
MOV A,#19H ;溢出一次相当于 100H=(FAH+10H)=19*BH+ 6*BH /A
MUL AB ;A=溢出部分的平均值,肯定小于0FF
MOV 5AH,A ;第一部分的平均值p1给5AH
MOV A,#6H
MOV B,5BH
MUL AB ;值给5BH,最大值是3CH,所以不用考虑溢出。
ADD A,5CH ;
MOV B,#10
DIV AB ;6B+s1的平均值p2
ADD A,5AH
MOV 5AH,A ;p1+p2
MOV 5BH,B
SJMP $
END
相似回答