(完整word版)基于proteus的AT89C51单片机实现计算器的加减乘数开方等功能
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
目录
一、任务说明 (2)
二、原理图绘制说明 (3)
三、流程图绘制以及说明 (5)
1显示程序设计 (5)
2键盘识别程序设计 (6)
3运算程序设计 (8)
4风鸣器程序设计 (9)
四、PROTEUS仿真说明 (10)
五、课程设计体会 (15)
附I:计算器电路原理图 (16)
附II:源程序代码 (17)
参考文献 (34)
一、任务说明
本设计是一个实现加、减、乘、除的计算器,它的硬件主要由四部分组成,一个AT89C51单片机芯片,一个八位共阳极的数码管,一个四乘四的键盘,一个排阻做P0口的上拉电阻,它可以实现结果低于65535的加、减、乘、除运算.
采用动态显示,由八位共阳极数码管通过P0口,P2口与单片机相连,数码管的A,B,C,D,E,F,G,DP分别依次与单片机的P0。
0—P0.7相连,P0口做为字码控制端,数码管的1,2,3,4,5,6,7,8各引脚分别与单片机的P2.0—P2。
7相连,P2口做为数码管的位控制端,动态显示是每次数码管只显示一位,由于人的视觉停留是0.05到0.2秒之间,当数码管依次点亮各个位时,使循环的频率高于人的视觉停留时间,人们就会认为数码管是同时点亮的,就可以达到动态显示的效果。
采用4*4键盘。
采用软件识别键值并执行相应的操作,键盘的第0行到第3行依次与单片机的P3.4—P3.7管脚相连,键盘的第0列到第3列依次与单片机的P1。
0—P1。
3管脚相连,程序运行时依次扫描各行,查询是否有键按下,如果有则进入键盘识别处理程序,实现相应的运算,然后通过数码管输出结果,如果没有按键就调用显示程序显示一个0,等待按键按下,在进入按键扫描程序。
这样循环执行。
基本功能如下:
1.计算器可显示8位数字,开机运行时,只有数码管最低位显示为“0",其余位全部不显示;
2。
第一次按下时,显示“D1”;第二次按下时,显示“D1D2”;第三次按下时,显示“D1D2D3”,8个全显示完毕,再按下按键下时,给出“嘀”提示音,并且输入的第九个数不接收,仍然显示原来的八位数;
3。
可以对计算结果小于65535的两个无符号数进行+、-、*、/运算,并显示计算结果,如果输入的预计算的数超过65535,则运算时报错,显示“ERROR",如果结果超过65535仍然报错,显示“ERROR”,以提示使用者输入错误,应清零后在从新输入。
4。
运算时,如果输入错了可按清零键清零,重新输入数据,运算过程中,如果运算的表达式是加、减、乘、除混合运算,可以连续运算,不需按等号键,运算规则是从左到右,不区分运算等级,即+、-、*、/认为是同级别的运算.
二、原理图绘制说明
首先得设计一个显示程序,这个显示程序应是动态显示,思路有两个:
(1)让P2口做位扫描,P0口做段码输出,在调用显示程序时,P2口循环选通数码管每一位的,P0口也依次循环输出相对应位的代码。
如何控制数字显示呢?可先将0-9、熄灭,11个段码放入列表中,在设置八个显示缓冲区,数码管要显示的数字就存放在这八个单元中,通过控制八个缓冲区的内容来控制输出的数字。
如:要显示的是1234则将缓冲区从低位开始依次放入04H、03H、02H、01H剩余四位放入11H(代表数码管熄灭的代码),要注意的是,当调用显示程序时,通过程序根据八个数码管缓冲区的数字调用相对应的代码就可以循环输出,但是我们看到的是同时显示1234,因为视觉停留的原故.当它的循环频率大于人的视觉停留时间,人们就认为它是同时显示的.虽然八个数码管都输出了,但是高四位送的代码是熄灭,即不显示,当
不输入数字时使八个缓冲区初始化为,第一位放00H,其余放11H,就可以只显示0,等待输入数据,这样就控制了显示位数实现了动态显示.
(2)让P2口做位扫描,P0口做段码输出,设置一个单元用来记录输入数字的位数,这样可以不用循环扫描每一位,而是根据输出位数判断扫描哪些位。
如上面的例子,当显示1234时,不用在向高四位送入11H,也不需要熄灭的代码了.调用显示程序时先选通第一位(最低位),送出代码1,然后判断是否显示完毕,(通过记录数字个数单元的内容减一是否得0来判断),如没显示完则显示下一位,如显示完则跳出。
在本设计中选用后者。
其次是设计键盘扫描程序,这里采用4*4矩阵键盘,通过软件识别,行和列可接在同个端口上,也可接在不同端口上,本设计行接在P3口的高四位,列接在P1口的低四位,通过循环扫描行,读取列的数据判断是否有键按下,如果有则调用按键识别程序识别是哪个键,执行相应的操作,按键识别是根据按键时得到的列代码与行代码组合,来判断是哪个键的。
按键识别后,如果是数字键则直接放入数码管显示缓冲区,如果再次有数字键按下,则应将缓存区的数字向高位移一位,将刚输入的数放入最低位,并且记录按键次数,每输入一个键值都调用显示程序显示出来,如果是运算符,则执行相应的运算,然后在调用显示程序显示结果。
最后是运算程序的加入,运算程序很简单,只要把+、—、*、/分别做成模块,用到时即可调用,本设计的难点是键盘识别和数值显示,因为这里边涉及到键盘输入的数值在内部要转换成10进制运算,运算结果要转换成各个位的显示数字输出。
在硬件的选择和连接上,单片机选择AT89C51,数码管选择共阳机八位数码管,键盘4*4矩阵键盘,P0口接上拉电阻,数码管的A,B,C,D,E,F,G,DP分别依次与单片机的P0.0—P0。
7管脚相连,P0口做为单片机的字码控制端,数码管的1,2,3,4,5,6,7,8各引脚分别与单
片机的P2。
0—P2.7管脚相连,键盘的第0行到第3行依次与单片机的P3。
4—P3.7,键盘的第0列到第3列依次与单片机的P1。
0—P1。
3,AT89C51接12MHZ晶振。
P3。
0接风鸣器.
计算器原理图如图1所示:
图1计算器原
理图
三、流程图绘制及
说明
1、显示程序设计
显示程序流程图如图2所示。
考虑到显示程应具有通用性,在不进行输入时显示0,输入时显示输入的数字或运算结果,而且要使8个数码管同时显示不同的数字,选用动态显示应是最佳的。
将30H-37H单元设置成数码管显示缓冲区,分别存放数码管各个位要显示的数据,40H单元作为输入数据的计数单元.因为运算结果超出范围时应报错,使数码管显示“ERROR”即可,将数码管的0-9的代码和“ERROR”代码存于LABLE1列表中。
当调用显示程序时,显示程序根据40H单元的记录的个数决定数码管显示的位数.如果输入错误将在数码管上显示“ERROR”.
这样就得到了显示程序的入口:30H—37H,依次存放个位-千万位。
40H,存放输出的数字位数。
出口:数码管,P0输出字段码P2输出位选码。
N
Y
图2数码管显示流程图
2、键盘识别程序设计
键盘识别程序流程图如图3所示。
首先将P3口送0EOH,将P1口先送1在读P1口的数据当P1口低四位全一时说明没有键按下,在扫描下一行,如果P1口不全一,则有键按下,将P3口高四位与P1口低四位组合成一个字节,放入R5寄存器中,按键去抖,判键是否松开,如松开则将得到的键值判别是哪个键,如果是数字键则首先将其对应的数字(按键代码对应如下表)放入缓冲区30H,同时将将键值放入结果缓冲区,并调用显示程序,显示键值,在调用扫描键盘程序,如果在有键值输入则将原来的数值在数码管显示缓冲区向高位依次移一位,将刚键入的数值放入最低位,并将原来的数值乘
十加上刚键入的数放人结果缓冲区,然后调用显示程序,如果是运算符,则记录运算符标志,加法用01H表示,减法用02H表示,乘法用03H表示,除法用04H表示,并将结果缓冲区的数转移到中间结果缓冲区,将结果缓冲区清零,等待输入运算数据,当按等号时,根据记录的运算符标志,判断是那种运算,执行运算将结果依次除10取余数放入结果显示缓冲区,调用显示程序。
依次循环执行。
Y
Y
Y
图3 键盘扫描流程图
3、运算程序设计
运算程序流程图如图4所示。
运算程序分四个模块,即加减乘除.分别采用两字节运算,因此运算结果不能超出两字节,否则会溢出.溢出时显示ERROR。
加法程序:入口:R0被加数低位字节地址指针,R1加数低位字节地址指针,R3字节数。
出口:R0和值地位字节地址指针,R3和值字节数。
运算时用R0,R1间接寻址,从低字节算起,高字节采用带进位加(ADDC),计算结果回送到R0所指的单元中,并将和字节数放入R3单元中,如果R3大于等于3说明溢出.
减法同加法类似,入口:R0被减数低位字节地址指针,R1减数低位字节地址指针,R3字
节数。
出口:R0和值地位字节地址指针,R3和值字节数。
只是判断溢出是通过
CY位,如果运算后CY位有借位,则将07H位置1,否则置0。
乘法程序:入口:R3,被乘数低位地址字节,R2,被乘数高位地址字节,R7,乘数低位地址字节,R6,乘数高位地址字节。
出口:R4,R5,R6,R7结果字节由高到低。
通过判断R5是否为零就可以知道运算结果是否溢出,如果溢出调用溢出程
序。
除法程序:入口:被除数放在R4R5R6R7,R4R5,内容为零,R4高R5低,除数放在R2R3,
R2高R3低。
出口:商放在R6R7,R6高R7低,余数放在R4R5,R4高R5低。
Y
N
N
Y
输入等号将运算结
果放入缓冲区并调
用显示程序显示结
图4运算程序流程图
3。
4风鸣器程序设计
这个程序是实现当输入八个数字时,如果在输入数字它便鸣叫,提示使用者输入以满,不允许在键入值,只需在键盘程序中,加入判别输入是否超过八个如果超过则调用风鸣器程序,使P3.0由低电平转入高电平,延迟1ms返回。
四、proteus仿真说明
1.开机显示:运行显示0,等待键入数值。
如图5所示。
图5 开机显示界面2.加法运算:键入被加数1000,显示1000。
如图6所示。
图6 键入加数1000显示
键入“+”显示原来键入的数值,等待键入加数。
如图7所示。
图7 键入+号显示界面
键入加数5000,显示5000。
如图8所示。
图8 键入加数5000显示界面键入“="显示结果,6000.如图9所示。
图9 键入=号显示界面3.减法运算:键入清零键“CL"。
如图10所示。
图10 清零显示界面
键入被减数4000,显示4000。
如图11所示。
图11 键入被减数4000界面键入“-”显示上次键入的值,等待键入减数。
如图12所示。
图12 键入—号显示界面
键入减数2000,显示录2000。
如图13所示.
图13键入减数显示界面
键入等号“=”显示结果2000。
如图14所示。
图14 键入=号显示界面
4.乘法运算:清零后键入被乘数5000,显示5000.如图15所示
图15 键入被乘数5000显示界面
键入乘号“*”,显示上一次键入的数,等待键入乘数,键入乘数“2”显示2.如图16所示。
图16键入乘数2显示界面
键入等号“=”显示结果10000.如图17所示。
图17键入=号结果显示界面
5.除法运算:清零后键入被除数3000,显示3000。
如图18所示.
图18 键入被除数3000显示界面
键入除号“/”显示上次键入的数,等待键入除数,键入除数50,显示50.如图19所示。
图19键入除数50显示界面
键入等号“=”显示结果60。
如图20所示。
图20 键入=号显示界面
7.运算错误:当运算的数值超出范围时将出现的信息.如:输入70000,后在按“+”时显示EEROR 因为70000>65535所以报错,显示:“ERROR”。
如图21所示。
图21 运算错误显示界面
五、体会及合理化建议
通过一周的忙碌,我先是学习了PROTEUS软件的使用,然后接到题目,按照题目所要求来进行分析,设计,连接电路图,调试,最终完成计算器的仿真。
接到题目后,我先是分析了题目中所涉及到的知识以及器件,然后按照分析,到图书馆和互联网上搜索了相关的内容,按照自己的构想和图书资料的提示,我初步设计了计算器的原理结构,把初步方案拿给老师建议,老师提出来了建议和改进之后,我又回去完善了设计,然后通过学习PROTEUS软件,让我很轻松的就掌握了如何在软件中建立原件,连线,并进行编程,调试,仿真等工作。
软件的强大功能使得在连接电路图时很顺利,程序编译阶段,通过提示的错误,我也进行了修改,并听取了老师和同学的建议,最终无错误,并对所设计的计算器电路进行了仿真。
最终顺利的实现了任务要求的所有功能,并且电路设计简单易读,构造巧妙,计算速度快,界面友好。
本次课程设计中,另我最难忘的是编程环节,很激动能够设计编程实际应用中的计算机,但是编程不像课本习题那样简单的几行来实现简单的功能,本次任务是实现一个简易功能的计算器,虽然只有加减乘除四则运算,但是编程过程中却用到了平常所学的所有知识,要考虑好知识之间的顺接,功能之间的联系,还有就是编程整体的简单易读,结构紧密有序,做到以上这些,我终于体会到了老师上课所说的,编程前画流程图的重要性,所以编程前,我按照以上的原则,先画出了流程图,然后按照流程图一步一步设计程序,在修改,调试,最终将不同功能块的程序拼接起来。
最终通过修改和调试完成了编程,并且进行验证也实现了任务要求的所有功能,那种喜悦无以伦比,第一次通过自己的努力和老师的帮助,即使完成了一个最简单的计算器功能也心中无比的喜悦。
在此感谢老师在我的课设过程中耐心的指导和提出的宝贵意见,使得我这次课程设计能够高效快速的完成。
附录I 计算机电路原理图
附录II源程序代码
设30H—37H单元为八个数码管从地位到高位所显示的内容。
38-3FH结果缓冲区.40H输入数据个数,41H加减乘除标志位50-53行地址。
42单元放运算符次数标志位。
ORG 0000H
LJMP START
ORG 0030H
START:MOV 30H,#00H ;;;;;;;;;;;;;;;初始化定义;;;;;;;;;;;
MOV 38H,#00H
MOV 39H,#00H
MOV 3AH,#00H
MOV 3BH,#00H
MOV 3CH,#00H
MOV 3DH,#00H
MOV 3EH,#00H
MOV 3FH,#00H
MOV 40H,#00H
MOV 41H,#00H
MOV 42H,#00H
MOV 43H,#00H
MOV 44H,#00H
MOV 50H,#0E0H ;;;;;;;;行定义;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV 51H,#0D0H
MOV 52H,#0B0H
MOV 53H,#70H
LOOP3: ACALL DISPLAY
MOV R0,#50H ;;R01表示启用R0;;;;;;;;寻键值;;;;;;;;;;;;
MOV R7,#04H ;;R71;;;;;循环4次;;;;;;;;;;;;;;;;;;;;;;; LOOP1:MOV A,@R0 ;;A1;;;;;;;;;;;;R0行号;;;;;;;;;;;;;;;;;;;;
MOV P3,A ;;A2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,#0FFH ;; A1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV P1,A ;;;A2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,P1 ;A1;;;;;;;;;;;读P1口;;;;;;;;;;;;;;;;;;
ANL A,#0FH
MOV R5,A ;A2;;;;;;;;;;;;;;;;;;;;;;;;
CJNE A,#0FH,LOOP2 ;;;;;;;;;;;;;;;;;;;;;判断有无按键;;;;;;;;;;;;;
INC R0
DJNZ R7,LOOP1 ;;;R72;;;;;;;;;;;;;;;;;;;
JMP LOOP3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LOOP2:MOV R4,#0A0H ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TFF:ACALL DELAY1mS ;;;;;;;;;;;延迟10MS;;;;;;;;
DJNZ R4,TFF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SS:MOV A,#0FFH
MOV P1,A
MOV A,P1 ;;;;;;;;;;;;;判键是否松开;;;;;;;;;;;;;;
ANL A,#0FH
CJNE A,#0FH,SS
MOV A,42H ;;;;;;;;;;;;;判断是否按+-×/号;;;;;;;;;
MOV R1,#30H ;;;;;;;;显示区低字节地址指针;;;;;;;;;;;;;;;;;;;;;;;
CJNE A,#01H,NEXT1
MOV 40H,#00H
MOV 42H,#00H
NEXT1:CJNE @R0,#0E0H,ROW2KEY ;;;;;;;;;111111;;;;;;;;;;R0行号;;;;;;;;;;;;;;
MOV A,R5 ;;;;A1;;R5列号;;;;;;;
ORL A,@R0 ;;;R02表示停用R0;;;;;;;;;;;;;;;;;;;;
CJNE A,#0EEH,KEY2 ;;;;A2;;;;;;;;;;;;;;;;
MOV A,40H
CJNE A,#08H,TW1
ACALL WARNNING
JMP LOOP3
TW1:INC 40H
MOV A,#07H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY2:CJNE A,#0EDH,KEY3
MOV A,40H
CJNE A,#08H,TW2
ACALL WARNNING
JMP LOOP3
TW2: INC 40H
MOV A,#08H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY3:CJNE A,#0EBH,KEY4
MOV A,40H
CJNE A,#08H,TW3
ACALL WARNNING
JMP LOOP3
TW3:MOV A,#09H
INC 40H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY4:ACALL JUDEG ;;计算结果放入3CH起始的单元;;;;;;;;;;;;;;;;;;;;;;;
ACALL CHANGE ;;;;;将结果放入显示缓冲区;;;;;;;;;;;;;;;;;;;;;;;;;
MOV 42H,#01H
MOV 41H,#04H ;;;;;;;;;;;;04 表示除法;;;;;;;;;;
JMP LOOP3
ROW2KEY:CJNE @R0,#0D0H,ROW3KEY ;;;;;;;;;;;;;;2222222222;;;;;;;;;;;;;;;;;;;;;;;
MOV A,R5
ORL A,@R0
CJNE A,#0DEH,KEY5
MOV A,40H
CJNE A,#08H,TW4
ACALL WARNNING
JMP LOOP3
TW4:INC 40H
MOV A,#04H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY5:CJNE A,#0DDH,KEY6
MOV A,40H
CJNE A,#08H,TW5
ACALL WARNNING
JMP LOOP3
TW5:MOV A,#05H
INC 40H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY6:CJNE A,#0DBH,KEY7
MOV A,40H
CJNE A,#08H,TW6
ACALL WARNNING
JMP LOOP3
TW6:MOV A,#06H
INC 40H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY7:ACALL JUDEG ;;;;计算结果放入3CH起始的单元;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ACALL CHANGE ;;;将结果放入显示缓冲区;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV 42H,#01H
MOV 41H,#03H ;;;;;;;;;;;;03表示乘法;;;;;;;;;;
JMP LOOP3
ROW3KEY:CJNE @R0,#0B0H,ROW4KEY ;;;;;;;;;;;;3333333333333;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,R5
ORL A,@R0
CJNE A,#0BEH,KEY8
MOV A,40H
CJNE A,#08H,TW7
ACALL WARNNING
JMP LOOP3
TW7:MOV A,#01H
INC 40H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY8:CJNE A,#0BDH,KEY9
MOV A,40H
CJNE A,#08H,TW8
ACALL WARNNING
JMP LOOP3
TW8:MOV A,#02H
INC 40H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY9:CJNE A,#0BBH,KEY10
MOV A,40H
CJNE A,#08H,TW9
ACALL WARNNING
JMP LOOP3
TW9: MOV A,#03H
INC 40H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
JMP LOOP3
KEY10:ACALL JUDEG ;;;;;;放入3CH起始的单元;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ACALL CHANGE ;;;;将结果放入显示缓冲区;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV 42H,#01H
MOV 41H,#02H ;;;;;;;;;;;;02 表示减法;;;;;;;;;;
JMP LOOP3
ROW4KEY:MOV A,R5
ORL A,@R0 ;;;;;;;;;;;;444444444444;;;;;;;;;;;;;;;;;;;;;;;;
CJNE A,#7EH,KEY11
JMP START ;;;;;;;;;;;;;;;;CLEAR;;;;;;;;;;;;;;;;;;;;;;;;;;; KEY11:CJNE A,#7DH,KEY12
MOV A,40H
JZ QQ
CJNE A,#08H,TW10
ACALL WARNNING
JMP LOOP3
TW10:MOV A,#00H
INC 40H
MOV 43H,A
ACALL MOVE
ACALL CHANGE11
QQ:JMP LOOP3
KEY12:CJNE A,#0BBH,KEY13 ;;;;;;;;;;;;;;;;;;;;;EQUEL;;;;;;;;;;;;;;;;;;;;;;;;
ACALL JUDEG ;;计算结果放入3CH起始的单元;;;;;;;;;;;;;;;
ACALL CHANGE ;;;;将结果放入显示缓冲区;;;;;;;;;;;;;;;;;;;;;;;;;;
JMP LOOP3
KEY13:ACALL JUDEG ;计算结果放入3CH起始的单元;;;;;;;;;;;;;;;;;;;;;;;;;
ACALL CHANGE ;;;;;将结果放入显示缓冲区;;;;;;;;;;;;;;;;;;;;;;;
MOV 42H,#01H
MOV 41H,#01H ;;;;;;;;;;;;01表示加法;;;;;;;;;;
JMP LOOP3
MOVE:MOV R1,#30H
MOV R6,40H
DDD:XCH A,@R1 ;;;;;;;;;;;;;交换指令;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NOP
NOP
NOP
NOP
INC R1 ;;;R1=30H
DJNZ R6,DDD
RET
加法程序:人口:R0,被加数低位字节地址指针,R1,加数低位字节地址指针,R3,字节数
出口:R0,和值地位字节地址指针,R3,和值字节数。
MAKEADD:MOV A,R0 ;;;;;;;保存地址;;;;;;;;;;;;;;;;;;;;
MOV R2,A
MOV A,R3
MOV R7,A
CLR C
LOP:MOV A,@R0
ADDC A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R7,LOP
JNC NEXT
INC R3
MOV @R0,#01H
NEXT:MOV A,R2 ;;;;;;;;回复地址;;;;;;;;;;;;;;;;;;;;;
MOV R0,A
RET
减法程序:入口:R0,被减数低位字节地址指针,R1,减数低位字节地址指针,R3,字节数出口:R0,差值地位字节地址指针,R3,差值字节数。
MAKESUB:CLR 07H
MOV A,R0
MOV R2,A
MOV A,R3
MOV R7,A
CLR C
LOP1:MOV A,@R0
SUBB A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R7,LOP1
JNC LOP2
SETB 07H
LOP2:MOV A,R2
MOV R0,A
RET
乘法程序: 入口:R3,被乘数低位地址字节,R2,被乘数高位地址字节,R7,乘数低位地址字节,R6,乘数高位地址字节,
出口:R4,R5,R6,R7结果字节由高到低
MAKEMUL:MOV A,R3
MOV B,R7
MUL AB
XCH A,R7
MOV R5,B
MOV B,R2
MUL AB
ADD A,R5
MOV R4,A
CLR A
ADDC A,B
MOV R5,A
MOV A,R6
MOV B,R3
MUL AB
ADD A,R4
XCH A,R6
XCH A,B
ADDC A,R5
MOV R5,A
MOV F0,C
MOV A,R2
MUL AB
ADD A,R5
MOV R5,A
CLR A
MOV ACC。
0,C
MOV C,F0
ADDC A,B
MOV R4,A
RET
除法程序:入口:被除数放在R4R5R6R7,R4R5,内容为零,R4高R5低,除数放在R2R3,R2高R3低,出口:商放在R6R7,R6高R7低,余数放在R4R5,R4高R5低
MAKEDIV:MOV A,R5
CLR C
SUBB A,R3
MOV A,R4
SUBB A,R2
JNC DIV11
MOV B,#16 DIV22:CLR C
MOV A,R7
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R5
RLC A
MOV R5,A
XCH A,R4
RLC A
XCH A,R4
MOV F0,C
CLR C
SUBB A,R3
MOV R1,A
MOV A,R4
SUBB A,R2
JB F0,DIV33
JC DIV44
DIV33:MOV R4,A
MOV A,R1
MOV R5,A
INC R7
DIV44:DJNZ B,DIV22
CLR F0
RET
DIV11:SETB F0
RET
CHANGE11:
MOV R0,#40H
CJNE @R0,#01H,TA1 ;;;;;;;;;;;;;;;;;;CHANGE;;;;;;;;;;;;;;;;;;;;;;
MOV 38H,43H
JMP TA2
TA1:MOV R3,38H
MOV R2,39H
MOV R6,#00H
MOV R7,#0AH
ACALL MAKEMUL
MOV 39H,R6
MOV 38H,R7
MOV 3AH,R5
MOV 3BH,R4
MOV R0,#38H
MOV R1,#43H
MOV R3,#02H
ACALL MAKEADD
TA2:RET
CHANGE:MOV 40H,#00H
MOV R0,#30H
MOV R7,3CH ;;;;;;;;;;;;;;3BH单元值;;;;;;;;;;;;;;
MOV R6,3DH
TD1:MOV R5,#00H
MOV R4,#00H
MOV R2,#00H
MOV R3,#0AH
INC 40H
ACALL MAKEDIV
MOV A,R5
MOV @R0,A
INC R0
MOV A,R6
CJNE A,#00H,TD1
MOV A,R7
CJNE A,#00H,TD1
RET
JUDEG:MOV A,3AH
JZ JUD1
ACALL ERROR
LJMP LOOP3
JUD1:MOV R1,#38H ;;;;;;;;计算中间结果;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,41H ;;;;R01;;;;;;;
CJNE A,#00H,TB
MOV 3CH,@R1
INC R1
MOV 3DH,@R1
JMP TBB
TB:CJNE A,#01H,TB1
MOV R0,#3CH ;;;41标志位1表示加法,2表示减法3表示乘法4表示除法;;;;;;;;;;;
MOV R3,#02H
ACALL MAKEADD
MOV A,R3
CJNE A,#03H,JUD2
ACALL ERROR
LJMP LOOP3
JUD2:JMP TBB
TB1:CJNE A,#02H,TB2
MOV R0,#3CH
MOV R3,#02H
ACALL MAKESUB ;;;将3B单元数加,减,乘,除38H单元放入3BH单元;;;;;;;
JNB 07H,JUD4
ACALL ERROR
LJMP LOOP3
JUD4:JMP TBB
TB2:CJNE A,#03H,TB3
MOV R3,3CH
MOV R2,3DH
MOV R6,39H
MOV R7,38H
ACALL MAKEMUL
MOV 3DH,R6
MOV 3CH,R7
MOV 3EH,R5
MOV 3FH,R4
MOV A,R5
JZ JUD3
ACALL ERROR
LJMP LOOP3
JUD3: JMP TBB
TB3:MOV R7,3CH
MOV R6,3DH
MOV R5,#00H
MOV R4,#00H
MOV R2,39H
MOV R3,38H
ACALL MAKEDIV
MOV 3CH,R7
MOV 3DH,R6 TBB:MOV 38H,#00H MOV 39H,#00H
MOV 3AH,#00H
MOV 3BH,#00H
RET
WARNNING:CLR P3.0
SETB P3.0
ACALL DELAY1mS
RET
ERROR:MOV R0,#30H
MOV A,#0AH
MOV R5,#05H
MOV 40H,#05H
ET:MOV @R0,A
INC R0
INC A
DJNZ R5,ET
RET
DISPLAY:MOV DPTR,#TABLE1 ;;;;;;;;;;;;;;;;;;;;;;DISPLAY;;;;;;;;;;;;;;
MOV R0,#30H
MOV R1,#80H
MOV R5,40H
NEXTF:MOV P2,R1
MOV A,@R0
MOVC A,@A+DPTR
MOV P0,A
ACALL DELAY1mS
MOV A,P2
RR A
MOV R1,A
INC R0
MOV A,R5
JZ AA
DJNZ R5,NEXTF
AA:RET
DELAY1mS:MOV R7,#02H ;;;DELAY1S;;;;;;;;;;;;;;;;;;
DL: MOV R6,#0FFH
DL6:DJNZ R6,DL6
DJNZ R7,DL
RET
TABLE1: DB 0C0H,0F9H,0A4H,0B0H, 99H
DB 92H,82H,0F8H,80H, 90H
DB 0CEH,0C0H,0CEH,0CEH,86H
END
参考文献:
1、何立民。
MCS—51系列单片机应用系统设计[M].北京:北京行天航空工业大学出版社,1990。
143-160.
2、李华.MCS—51系列单片机实用接口计数[M].北京:北京行天航空工业大学出版社,
1993.148-158.
3、杨欣。
51单片机应用从零开始[M]。
北京:清华大学出版社,2008。
88-107。
4、兰吉昌.51单片机应用设计百例[M].北京:化学工业出版社,2009。
137-15.
(完整word版)基于proteus的AT89C51单片机实现计算器的加减乘数开方等功能
5、吴银琴.51单片机实践教程[M].北京:科学出版社,2011.127-139.
6、赵建领.51单片机开发与应用技术详解[M].北京。
北京航空航天大学出版社,2010。
167-191。
7、李学海.标准80C51单片机基础教程:原理篇[M].北京。
北京航空航天大学出版社,2006。
183-193.
41。