1、 目录一设计任务和要求 21.1概要 .21.3 设计要求 2二硬件设计 .32.1总设计思路 .32.2 总原理图 32.3最小系统 4三软件设计 .53.1 主程序 53.2 显示程序设计(程序见附录) 73.3键盘识别程序设计(程序见附录) .83.4运算程序设计(程序见附录) 11四Keil 调试与仿真 134.1 keil的使用方法 13五总电路图 .14六 总结 .15七参考文献 .16附录A .17程序清单 .17附录B .27元器件清单 271一设计任务和要求1.1概要简易计算器的原理与设计是单片机课程设计课题中的一个。在完成理论学习和必要的实验后,我们掌握了单片机的基本原理以
2、及编程和各种基本功能的应用,但对单片机的硬件实际应用设计和单片机完整的用户程序设计还不清楚,实际动手能力不够,因此对该课程进行一次课程设计是有必要的。1.2设计任务本次课程设计,我们选择的课题是单片机数字计算器硬软件设计 ,设计任务为: 1.扩展4*4键盘,其中10个数字,5 个功能键,1个清零2.强化对于电路的焊接3.使用五位数码管接口电路4. 完成十进制的四则运算(加、减、乘、除); 5. 实现结果低于五位的连续运算;6. 使用keil 软件编写程序,使用汇编语言; 7. 最后用ptoteus模拟仿真;8.学会对电路的调试1.3 设计要求单片机课程设计既要让我们巩固课本学到的理论,还要学习
3、单片机硬件电路设计和用户程序设计,使所学的知识更深一层的理解,数字计算器原理与硬软件的课程设计主要是通过学生独立设计方案并自己动手用计算机电路设计软件,编写和调试,最后仿真用户程序,来加深对单片机的认识,充分发挥学生的个人创新能力,并提高对单片机的兴趣,同时学习查阅资料、参考资料的方法。 通过实践更好的了解单片机,巩固了键盘扫描,数码管,等一系列单片机的知识。本次设计我们需要AT89C51芯片,要充分理解各个管脚的用途;还是用了两个四位一体的共阳极的数码管,要知道其位控和字控的引脚位置;还用了4*4的键盘;采用手电复位。 而我的设计任务是计算器的软件部分,硬件部分参见同组的人。2二硬件设计2.
4、1总设计思路本设计是一个实现加、减、乘、除的计算器,它的硬件主要由四部分组成,一个AT89C51单片机芯片,两个四位一体的共阳极的数码管,一个4*4的键盘,一个排阻(10K)做P0口的上拉电阻(接线图再总电路图),它可以实现结果低于65535的加、减、乘、除运算。首先.显示部分,让P2口做位扫描,P0 口做段码输出,设置一个单元用来记录输入数字的位数,这样可以不用循环扫描每一位,而是根据输出位数判断扫描哪些位。如当显示1234 时,不用在向高四位送入11H,也不需要熄灭的代码了。调用显示程序时先选通第一位(最低位),送出代码1,然后判断是否显示完毕,(通过记录数字个数单元的内容减一是否得0 来
5、判断),如没显示完则显示下一位,如显示完则跳出。其次是设计键盘扫描程序,这里采用4*4矩阵键盘,通过软件识别,行和列可接在同个端口上,也可接在不同端口上,本设计行接在P3口的高四位,列接在P1 口的低四位,通过循环扫描行,读取列的数据判断是否有键按下,如果有则调用按键识别程序识别是哪个键,执行相应的操作,按键识别是根据按键时得到的列代码与行代码组合,来判断是哪个键的。按键识别后,如果是数字键则直接放入数码管显示缓冲区,如果再次有数字键按下,则应将缓存区的数字向高位移一位,将刚输入的数放入最低位,并且记录按键次数,每输入一个键值都调用显示程序显示出来,如果是运算符,则执行相应的运算,然后在调用显
6、示程序显示结果。最后是运算程序的加入,运算程序很简单,只要把、-、* 、/分别做成模块,用到时即可调用,本设计的难点是键盘识别和数值显示,因为这里边涉及到键盘输入的数值在内部要转换成10 进制运算,运算结果要转换成各个位的显示数字输出。2.2 总原理图P3.4P3.7行输入4*4矩阵键盘P0.0P0.7AT89C51P2.0P2.7 两个四位数码管显示初始化,各位显0根据按键,计算结果显示通过三级管放大信号P0=FEH 左移进行位控P1.0P1.3列扫描通过P0口进行位控32.3最小系统手动复位:由电容串联电阻构成,系统一上电,RST脚将会出现高电平 ,并且,这个高电平持续的时间由电路的RC值
7、来决定.典型的51单片机当RST脚的高电平持续两个机器周期以上就将复位。晶振电路:典型的晶振取11.0592MHz(因为可以准确地得到9600波特率和19200波特率,用于有串口通讯的场合)/12MHz(产生精确的uS级时歇,方便定时操作)单片机:一片AT89S51/52或其他51系列兼容单片机特别注意:对于31脚(EA/Vpp),当接高电平时,单片机在复位后从内部ROM的0000H开始执行;当接低电平时,复位后直接从外部 ROM的0000H开始执行。图2-14XTAL218XTAL119ALE30 EA31 PSEN29RST9P0.0/AD0 39P0.1/AD1 38P0.2/AD2 3
8、7P0.3/AD3 36P0.4/AD4 35P0.5/AD5 34P0.6/AD6 3P0.7/AD7 32P1.01 P1.12P1.23 P1.34P1.45 P1.56P1.67 P1.78P3.0/RXD 10P3.1/TXD 1P3.2/INT0 12P3.3/INT1 13P3.4/T0 14P3.7/RD 17P3.6/WR 16P3.5/T1 15P2.7/A15 28P2.0/A8 21P2.1/A9 2P2.2/A10 23P2.3/A1 24P2.4/A12 25P2.5/A13 26P2.6/A14 27U1AT89C51X1CRYSTALC11nFC21nFGNDC
9、310uR233ufR133ufGND三软件设计3.1 主程序30H37H存储数码管从低位到高位的所显示的数,383FH 结果缓冲区。40H输入数据个数,41H加减乘除标志位 5053行地址。42单元放运算符次数标志位。 一上电复位后,程序开始运行,跳转到主程序进行初始化,然后调用用显示子程序显示初始状态个位上为零。然后调用键盘扫描子程序,不断循环判断是否有键按下,如有键按下时,延时防抖和判断按键是否松开,松开说明确定有键按下,开始分析按下的是功能键还是数字键,按不同键进行处理;若是数字键,则输入该数字,再调用显示子程序显示;若是功能键中的清除键,则相当于复位,清除状态,个位保持显示零,直到有
10、键再次输入;若是+,*,/ 功能键时,要根据上次功能键计算的结果或输入的数据进行计算同时保图2 -2 最小系统5存结果和功能,同时也要等再次输入数据,也要调用显示子程序显示结果。主程序主要是用来进行初始化的,调用其他子程序,清空各个标志位,清空缓存区,读取键码,判断功能,在LED上作出回应,主程序流程图如图所示。NYNYY是数字键 是功能键主程序:ORG 0000H LJMP MAINORG 0030HMAIN: MOV 30H,#00H ;初始化定义,各位在最开始永远显示0;MOV 38H,#00H ;383FH结果缓冲区;MOV 39H,#00H MOV 3AH,#00H MOV 3BH,
11、#00HMOV 3CH,#00H开始初始化参数LED显示是否有键按下?防抖,是否有键松开分析键值功能键根据上次功能键和输入的数据计算结果保存结果和功能键结果送显示缓存等待数值输入清零键状态清零数字键输入数值数值送显示缓存图3-1 主程序流程图6MOV 3DH,#00HMOV 3EH,#00HMOV 3FH,#00HMOV 40H,#00H ;输入数据个数; MOV 41H,#00H ;功能键标志位;MOV 42H,#00H ;功能键按键次数MOV 43H,#00H ;输入的数据暂存区MOV 44H,#00HMOV 50H,#0E0H ;行定义MOV 51H,#0D0HMOV 52H,#0B0H
12、MOV 53H,#70HACALL DISPLAY ;调用显示子程序,显示初始状态ACALL KEY ;判断是否有键按下MOV R4,#0A0H ACALL DELAY-1ms ;防抖,延时10msACALL SS ;判断键是否松开3.2 显示程序设计(程序见附录)显示程序流程图如图3-2。我的显示程序是这样设计的,因为考虑到显示程应具有通用性,在不进行输入时显示0,输入时显示输入的数字或运算结果,而且要使8个数码管同时显示不同的数字,选用动态显示应是最佳的。将30H-37H单元设置成数码管显示缓冲区,分别存放数码管各个位要显示的数据,40H单元作为输入数据的计数单元。因为运算结果超出范围时应
13、报错,使数码管显示“Error”即可,将数码管的09的代码和“Error”代码存于LABLE1列表中。当调用显示程序时,显示程序根据40H单元的记录的个数决定数码管显示的位数。如果输入错误将在数码管上显示“Error”。当计算结果超出65536时,数码管上也同样显示Error。在调用显示子程序时,要设定数据缓冲区指针,和循环次数存入R5中,R1=#FEH位控制,然后根据缓冲区的数用查表指令在表中找出该数字的段码,并将该段码送入P0口,再通过对R1中的位控进行移位选择,使要显示的位数显示,同时根据40H中的数据个数控制循环次数。这样就得到了显示程序的入口:30H-37H,依次存放个位千万位。40
14、H,存放输出的数字位数。显示程序的出口:数码管,通过查表指令P0输出字段码 ,P2输出位选码。图3-27数码管显示判断显示是否完毕返回否是初始化R0=30H 缓冲区指针,R1位控制, R5循环控制次数R0=30H,R1=#FEH,R5=40H开始3.3键盘识别程序设计(程序见附录) 键盘识别是这样设计的,首先将P3口送0EOH,将P1口先送FFH在读P1口的数据当P1口低四位全一时说明没有键按下,在扫描下一行,如果P1 口不全一,则有键按下,将P3口高四位与 P1口低四位组合成一个字节,放入 R5寄存器中,按键去抖,判键是否松开,如松开则将得到的键值判别是哪个键,如果是数字键则首先将其对应的数
15、字(按键代码对应如下表1 )放入缓冲区30H ,同时将键值放入结果缓冲区,并调用显示程序,显示键值,在调用扫描键盘程序,如果在有键值输入则将原来的数值在数码管显示缓冲区向高位依次移一位,将刚键入的数值放入最低位,并将原来的数值乘十加上刚键入的数放人结果缓冲区,然后调用显示程序,如果是运算符,则记录运算符标志,加法用01H表示, 减法用02H表示,乘法用03H表示,除法用04H 表示,并将结果缓冲区的数转移到中间结果缓冲区,将结果缓冲区清零,等待输入运算数据,当按等号时,根据记录的运算符标志,判断是那种运算,执行运算将结果依次除10取余数放入结果显示缓冲区,调用显示程序。依次循环执行。(流程图如
16、下)表1键码 键值 键码 键值8EE 7 BE 1 ED 8 BD 2 EB 9 BB 3 E7 / B7 - DE 4 7E CL DD 5 7D 0 DB 6 7B = D7 * 77 + 9开始扫描第一一行是否有键按下Y 判断键值N扫描第二行数字键放入显示缓冲区运算符修改标志位调用显示程序显示数字进行运算运算结果放入显示缓冲区是否有键按下N扫描第三行是否有键按下N扫描第四行是否有键按下N 图3-3 键盘扫描流程图YYY103.4运算程序设计(程序见附录)运算程序分四个模块,即加减乘除。分别采用两字节运算,因此运算结果不能超出两字节,否则会溢出。溢出时显示ERROR。加法程序:入口:R0被
17、加数低位字节地址指针,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, 乘数高位
18、地址字节。出口:R4,R5,R6,R7结果字节由高到低。通过判断R5是否为零就可以知道运算结果是否溢出,如果溢出调用溢出程序。除法程序:入口:被除数放在R4R5R6R7,R4R5,内容为零,R4高R5低,除数放在R2R3,R2 高R3低。出口:商放在R6R7,R6 高R7低,余数放在R4R5,R4高R5低 。 运算程序运行时,首先得到的键值是否是第一个,若是则将该键值直接转存到结果缓冲区中,即38H 开始的4个单元中;若不是则将上次的数字乘以10 再加上本次输入放入结果缓冲区(38H开始的),然后再判断是否有按下运算符,若没有,则继续等待键值的再次输入;若有按下运算符,则要将结果缓冲区的值放入
19、中间结果缓冲区中(3CH开始的单元),同时要判断按下的运算符是什么运算符(+ :01H;- :02H;*:03H;/:04H),然后判断是否有第二个值输入,若没则继续等待,若有则放入结果缓冲区中,当扫描到等于号时,则根据输入的运算符计算,并把运算结果放入缓冲区,并调用显示子程序显示结果12开始得到键值判断是否是第一个数Y将数值直接转移到结果缓冲区,38H单元开始的四个单元里N数否按过运算符将上次的数值乘10加上本次输入放入结果缓冲区(38H 单元开始)NY判断是是哪种运算符标志位记录运算种类如:加法 41H=#01H减法 41H=#02H乘法 41H=#03H除法 41H=#04H将第一次键入
20、的数(在38H起始的单元)转移到中间结果缓冲区自3CH 开始的单元是否键入第二次数值NY等待键入数值将数值放入结果缓冲区38H其实单元里输入等号将运算结果放入缓冲区并调用显示程序显示结果 图3-4运算程序流程图13四Keil 调试与仿真4.1 keil的使用方法KEIL C51标准 C编译器是众多单片机应用开发的优秀软件之一,它集编辑、编译、仿真于一体,支持汇编、PLM 语言和 C 语言的程序设计。1. 启动 KEIL C51 进入编辑界面 建立一个新工程:单击Project菜单,在弹出的下拉菜单中选中 New Project选项。选择保存路径,输入工程文件名。2. 工程文件保存完毕之后,提示
21、选择单片机的型号。KEIL支持近乎所有51核的单片机。单击 File菜单,选择New。3.文件保存:使用汇编编写,文件后缀名为.asm或 a51。完成后,单击“保存”按钮保存文件。4.在Source Group 上单击右键,找到刚才保存的源文件 ,然后添加ADD 5. 在编辑完成之后,需要进行程序的编译。点开Project选项,单击 Build target;或是利用快捷键 F7。 6. 在程序调试的时候,点击Debug 选项,选择 Start/Stop Debug Session。 7. 以上是使用 KEIL建立一个完整工程文件的过程。下载到单片机之中,则需要 生 成 HEX 文 件 。 单
22、 击 “Project” 菜 单 , 再 在 下 拉 菜 单 中 单 击出现选项对话框。在选项对话框的“Output”页面对话框中,单击“Create HEX File” 选项,使程序编译后产生 HEX 代码,供下载器软件使用。4.2.调试过程在Debug调试下,如有错误时,下面窗口将有提示说明错误个数和具体哪一行有错,还有对于错误的说明,大多数格式使用不当,此时在那一行前后仔细检查,要考虑格式,语法等基本性错误。即使调试没错时,程序也不是代表完全正确,需要结合硬件来确定改程序的功能是否完全实现了。图4-1keil调试图14五总电路图XTAL218XTAL119ALE30EA31PSEN29R
23、ST9P0./AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD63P0.7/AD732P1.01P1.2P1.23P1.34P1.45P1.56P1.67P1.78P3.0/RXD10P3.1/TXD1P3.2/INT012P3./INT113P3.4/T014P3.7/RD17P3.6/WR16P3.5/T115P2.7/A1528P2.0/A821P2.1/A92P2./A1023P2.3/A124P2.4/A1225P2.5/A1326P2.6/A1427U1AT89C51X112MC13uFC23uFGND 2
24、34567891RP1RESPACK-8R210kR1470 C510uFR310kR410kR510kR610k+5vQ32N3703Q12N3703 Q22N3703 Q42N3703 Q52N3703 Q62N3703 Q72N3703 Q82N3703BR1BRIDGETR1TRAN-2PSVI1 VO3GND2U27805C310uFC410u C510uR710kR810kR910kR110kR110kR10kR1310k R1410k图5 总电路图156总结课程设计是培养学生综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和
25、考察过程。作为电子信息工程专业的学生来说掌握单片机的开发技术是十分重要的。这次我们的课程设计内容是一个简易的计算器。对于我们这些工科学生来说,这是一次考验。怎么才能找到课堂所学与实际应用的最佳结合点?怎样让自己的业余更接近专业?怎样让自己的计划更具有序性,而不会忙无一用?这都是我们所要考虑和努力的。这次课程设计我学到很多很多的东西,学会了怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识,掌握了一种系统的研究方法,可以进行一些简单的编程。通过这次课程设计使我懂得了理论与实际相结合是很重要
26、的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。然而我们也有许多不足之处。在软件编程时一定要考虑周到,要有耐心要仔细。还要与硬件相联系起来,脱离了实物一切都是假的。在理论上往往是可行的,然而当把程序烧入芯片,进行调试时就会遇到这样那样的的问题。最糟的是当我们辛苦把实物完成,而那电路有完全没反应,与我们的设想完全不同,而我们又不知道是软件问题还是硬件问题时,就要静下心来,一步一步来,从硬件的的芯片开始检查是否短路等等,而软件又要不断地进行仿真调试。然而我们遇到的问题除了焊接时可能导致的短路外,还
27、应电压不稳定或过大而导致芯片被烧毁,总而言之,我们还是缺少对芯片和各种器件的了解,无法准确的判断出什么样的现象将是由原因引起的。就拿我们来讲吧,当我们把电路焊接好后,加入程序进行调试时发现数码管不显示,此时我们要检查电路时我们才发现焊接时电路线的排版不是很好,线一多就无法判断到底哪里有错,简直让人眼花,最后我们不得不宣布放弃这块,重新买齐器件进行再次焊接,这次我们吸取了上次教训,采用排针排线的方法方便与检查和调试,可结果仍不理想,数码管全显,好像程序根本没运行,然而由于我们进行仿真过,所以唯一认为的是电路有问题,我们花了一天时间检查是否把那里短路了,或接了不该接的,最后还是不成功,只好在第二天
28、进行简单的程序来检查时,才发现芯片坏了,也只好换芯片,很快变成功了,当我们会宿舍再次接通电源时,又发现程序好像没走,不得又去实验室检查发现有坏了,才知道我们用的电源有问题。哎!真是多磨难啊!但结果还是令人兴奋的。16七参考文献1.http:/ 系列单片机实用接口计数 M.北京:北京行天航空工业大学出版社,1993.148-158.6. 单片机应用技术(汇编语言),中国劳动社会保障出版社,2006.67.单片机原理及应用技术 主编:范力旻 出版社:电子工业出版社8.51单片机应用程序开发与实践 编著:常敏、汪涵、方江波等 出版社:电子工业出版社9.PIC单片机典型模块设计实例导航 出版社:人民邮
29、电出版社10.单片机接口技术实用子程序 编著:陈小忠、黄宁、赵小侠出版社:人民邮电出版社17附录A程序清单设30H-37H单元为八个数码管从地位到高位所显示的内容.38 3FH结果缓冲区。40H输入数据个数 ,41H加减乘除标志位 5053行地址。42单元放运算符次数标志位。ORG 0000H LJMP STARTORG 0030HSTART:MOV 30H,#00H ;初始化定义MOV 38H,#00H ;383FH结果缓冲区;MOV 39H,#00H MOV 3AH,#00H MOV 3BH,#00HMOV 3CH,#00HMOV 3DH,#00HMOV 3EH,#00HMOV 3FH,#
30、00HMOV 40H,#00H ;输入数据个数; MOV 41H,#00H ;功能键标志位;MOV 42H,#00H ;功能键按键次数MOV 43H,#00H ;输入的数据暂存区MOV 44H,#00HMOV 50H,#0E0H ;行定义MOV 51H,#0D0HMOV 52H,#0B0HMOV 53H,#70HLOOP3:ACALL DISPLAYKEY:MOV R0,#50H ;R01表示启用,R0寻键值;MOV R7,#04H ;R7循环4次LOOP1:MOV A,R0 ;R0行号MOV P3,A ;给P3口的高四位轮流送0,低四位为0MOV A,#0FFH MOV P1,A ;给P1口
31、送1MOV A,P1 ;读P1口ANL A,#0FH ;A的高四位为0 ,保存第四位,即保 ;存按键状态MOV R5,A ;将P3 口和P1口结合暂存R5 CJNE A,#0FH,LOOP2 ;判断有无按键,如不等则该行有键按下,;跳转到LOOP2进行防抖,;若相等则该行无键,继续判断下一行。18INC R0 ;指针下移,继续给下一行送0DJNZ R7,LOOP1 ;要判断四行,R7-1 不等于0时四行判断完仍无键按下时,继续循环扫描是否有键按下。;等于0时,跳转到LOOP3开始分析JMP LOOP3 LOOP2:MOV R4,#0A0H ;延迟1ms*10=10msDELAY:ACALL D
32、ELAY1mS DJNZ R4,TFF;SS: MOV A,#0FFH MOV P1,A MOV A,P1 ;判键是否松开 ; ANL A,#0FHCJNE A,#0FH,SS ;松开,该键按下有效MOV A,42H ;判断是否按 /号MOV R1,#30H ;显示区低字节地址指针CJNE A,#01H,NEXT1 ;等于01H时是+,继续向下运行,不等 ;于时跳转到NEXT1 MOV 40H,#00H ;设定数据个数MOV 42H,#00H ;运算符标识数NEXT1: CJNE R0,#0E0H,ROW2KEY ;R0行号与第一行比较,判断是;否是第一行有键按下,如不等,;则转第二行判断,如
33、是则进行 ; 列判断MOV A,R5 ;R5列号,判断是该行的具体哪一个键按下ORL A,R0 ;表示停用R0,生成按键的键值存入ACJNE A,#0EEH,KEY2 ;判断该按下的是7吗,若不是跳转继续判断 MOV A,40H ;数据个数给 ACJNE A,#08H,TW1 ;判断数据个数是否等于8,不等于时可继续输 ;入当满8位时保持不变JMP LOOP3 ;调用显示程序显示TW1:INC 40H ;有数据输入时,数据个数增加MOV A,#07H ;首先输入的7暂存于43HMOV 43H,A ACALL MOVE ;调用交换程序,即将依次输入的数往后19推移ACALL CHANGE11 J
34、MP LOOP3 KEY2:CJNE A,#0EDH,KEY3 ;判断是按下 8键吗,不是转下一个MOV A,40H CJNE A,#08H,TW2 ;判断是否已满8 位,不满时转TW2JMP LOOP3 ;显示TW2: INC 40H ;数据个数增加MOV A,#08H ;输入值是8MOV 43H,AACALL MOVE ACALL CHANGE11JMP LOOP3 ;显示数据KEY3:CJNE A,#0EBH,KEY4 ;判断是9吗,不是继续判断下一个MOV A,40HCJNE A,#08H,TW3 ;是否满8 位JMP LOOP3 ;显示TW3:MOV A,#09HINC 40HMOV
35、 43H,AACALL MOVEACALL CHANGE11JMP LOOP3KEY4:ACALL JUDEG ;计算结果放入3CH起始的单元;ACALL CHANGE ;将结果放入显示缓冲区;MOV 42H,#01HMOV 41H,#04H ;04 表示除法JMP LOOP3ROW2KEY:CJNE R0,#0D0H,ROW3KEY ;第二行 MOV A,R5ORL A,R0CJNE A,#0DEH,KEY5 ;判断是否是4MOV A,40HCJNE A,#08H,TW4JMP LOOP3TW4: INC 40HMOV A,#04HMOV 43H,A ;将 4暂存ACALL MOVEACAL
36、L CHANGE11JMP LOOP3KEY5: CJNE A,#0DDH,KEY6 ;判断是否是5MOV A,40H 20CJNE A,#08H,TW5JMP LOOP3TW5: MOV A,#05HINC 40HMOV 43H,AACALL MOVEACALL CHANGE11JMP LOOP3KEY6: CJNE A,#0DBH,KEY7 ;判断是否是6MOV A,40HCJNE A,#08H,TW6JMP LOOP3TW6: MOV A,#06HINC 40HMOV 43H,AACALL MOVEACALL CHANGE11JMP LOOP3KEY7: ACALL JUDEG ;计算结
37、果放入3CH起始的单元;ACALL CHANGE ;将结果放入显示缓冲区MOV 42H,#01HMOV 41H,#03H ;03表示乘法JMP LOOP3ROW3KEY:CJNE R0,#0B0H,ROW4KEY ;第三行 MOV A,R5ORL A,R0CJNE A,#0BEH,KEY8 ;判断是否是1MOV A,40HCJNE A,#08H,TW7JMP LOOP3TW7: MOV A,#01HINC 40HMOV 43H,AACALL MOVEACALL CHANGE11JMP LOOP3KEY8:CJNE A,#0BDH,KEY9 ;判断是 2MOV A,40HCJNE A,#08H,
38、TW8JMP LOOP3TW8:MOV A,#02HINC 40HMOV 43H,AACALL MOVE21ACALL CHANGE11JMP LOOP3KEY9:CJNE A,#0BBH,KEY10 ;判断是3MOV A,40HCJNE A,#08H,TW9JMP LOOP3TW9: MOV A,#03HINC 40HMOV 43H,AACALL MOVEACALL CHANGE11JMP LOOP3KEY10:ACALL JUDEG ;放入3CH起始的单元ACALL CHANGE ;将结果放入显示缓冲区;MOV 42H,#01HMOV 41H,#02H ;02 表示减法JMP LOOP3R
39、OW4KEY:MOV A,R5 ORL A,R0 CJNE A,#7EH,KEY11JMP START ;clear,相当于复位,程序从头开始KEY11:CJNE A,#7DH,KEY12 ;判断是0MOV A,40HJZ QQ ;显示 CJNE A,#08H,TW10JMP LOOP3TW10:MOV A,#00HINC 40HMOV 43H,AACALL MOVEACALL CHANGE11QQ: JMP LOOP3 ;显示KEY12:CJNE A,#07BH,KEY13 ;EQUEL;ACALL JUDEG ;计算结果放入3CH起始的单元ACALL CHANGE ;将结果放入显示缓冲区J
40、MP LOOP3KEY13:ACALL JUDEG ;计算结果放入3CH起始的单元ACALL CHANGE ;将结果放入显示缓冲区MOV 42H,#01HMOV 41H,#01H ;01表示加法JMP LOOP3MOVE:MOV R1,#30HMOV R6,40H22DDD: XCH A,R1 ;交换指令,是高位的数后移NOPNOPNOPNOPINC R1 ;R1=30H,开始下移DJNZ R6,DDDRET加法程序:人口:R0被加数低位字节地址指针,R1加数低位字节地址指针,R3字节数出口: R0和值的位字节地址指针,R3和值字节数。MAKEADD:MOV A,R0 ;保存地址MOV R2,
41、AMOV A,R3MOV R7,ACLR CLOP: MOV A,R0ADDC A,R1MOV R0,AINC R0INC R1DJNZ R7,LOP ;由字节数决定循环次数JNC NEXT ;判断是否溢出INC R3 ;若大于3 则溢出MOV R0,#01HNEXT: MOV A,R2 ;回复地址MOV R0,ARET减法程序:入口:R0, 被减数低位字节地址指针,R1, 减数低位字节地址指针,R3,字节数出口:R0,差值地位字节地址指针,R3, 差值字节数。MAKESUB:CLR 07HMOV A,R0MOV R2,AMOV A,R3MOV R7,ACLR CLOP1:MOV A,R0SU
42、BB A,R1MOV R0,AINC R0INC R1DJNZ R7,LOP123JNC LOP2 ;判断是否溢处SETB 07H ;溢出时07H 置1LOP2:MOV A,R2MOV R0,ARET乘法程序: 入口:R3 被乘数低位地址字节,R2 被乘数高位地址字节, R7乘数低位地址字节,R6乘数高位地址字节,出口:R4,R5,R6,R7结果字节由高到低MAKEMUL: MOV A,R3MOV B,R7MUL ABXCH A,R7MOV R5,BMOV B,R2MUL ABADD A,R5MOV R4,ACLR AADDC A,B MOV R5,AMOV A,R6MOV B,R3MUL A
43、BADD A,R4XCH A,R6XCH A,BADDC A,R5MOV R5,AMOV F0,CMOV A,R2MUL ABADD A,R5MOV R5,ACLR AMOV ACC.0,CMOV C,F0ADDC A,BMOV R4,ARET除法程序:入口:被除数放在R4R5R6R7 、R4R5内容为零,R4高R5低,除数放在R2R3,R2 高R3低,出口:商放在R6R7,R6高R7低,余数放在R4R5,R4高R5低MAKEDIV : MOV A,R5CLR C24SUBB A,R3MOV A,R4SUBB A,R2JNC DIV11MOV B,#16DIV22: CLR CMOV A,R7
44、RLC AMOV R7,AMOV A,R6RLC AMOV R6,AMOV A,R5RLC AMOV R5,AXCH A,R4RLC AXCH A,R4MOV F0,CCLR CSUBB A,R3MOV R1,AMOV A,R4SUBB A,R2JB F0,DIV33JC DIV44DIV33: MOV R4,AMOV A,R1MOV R5,AINC R7DIV44: DJNZ B,DIV22CLR F0RETDIV11: SETB F0RETCHANGE11:MOV R0,#40HCJNE R0,#01H,TA1 ;CHANGEMOV 38H,43HJMP TA2TA1:MOV R3,38H
45、MOV R2,39HMOV R6,#00HMOV R7,#0AH25ACALL MAKEMULMOV 39H,R6MOV 38H,R7MOV 3AH,R5MOV 3BH,R4MOV R0,#38HMOV R1,#43HMOV R3,#02HACALL MAKEADDTA2: RETCHANGE:MOV 40H,#00HMOV R0,#30H MOV R7,3CH ;3BH单元值;MOV R6,3DHTD1: MOV R5,#00HMOV R4,#00HMOV R2,#00HMOV R3,#0AHINC 40HACALL MAKEDIVMOV A,R5MOV R0,AINC R0MOV A,R6
46、CJNE A,#00H,TD1MOV A,R7CJNE A,#00H,TD1RETJUDEG:MOV A,3AHJZ JUD1ACALL ERRORLJMP LOOP3JUD1:MOV R1,#38H ;计算中间结果;MOV A,41H CJNE A,#00H,TB ;有运算符时转移MOV 3CH,R1INC R1MOV 3DH,R1JMP TBBTB: CJNE A,#01H,TB1 ;判断加法MOV R0,#3CH ;41H标志位,1表示加法,2表示减法,3表示乘法,4 ;表示除法MOV R3,#02H26ACALL MAKEADDMOV A,R3CJNE A,#03H,JUD2 ;字节数大于3时溢出ACALL ERROR ;显示错误errorLJMP LOOP3JUD2:JMP TBBTB1:CJNE A,#02H,TB2 ;判断减法MOV R0,#3CHMOV R3,#02HACALL MAKESUB ; 将3B单元数加减乘除,38H单元