电子计算器(汇编)

1. 电子计算器简介

1.1 设计目的

  电子计算器相比于人手算可谓有着不可或缺的优势,首先电子计算器有着极高的计算速度,其次它还可以保证很高的稳定性和准确性,这对于学理工科的我们来说可谓是一大帮手,同时由于51单片机的价格低廉,结构简单,这从而使得利用单片机来设计电子计算器拥有极高的价值性和实用性。

 

1.2 设计要求

  本课题的主要内容是采用单片机实现一个简单的电子计算器,通过这个实习进一步加深《C语言程序设计》、《单片机原理及应用》等相关课程中的理论知识,熟练掌握单片机的编程、调试和应用系统的开发。

基本要求:

(1)行列式按键的读取、数码管动态扫描显示;

(2)实现计算结果在0~9999范围内的正负整数的加、减、乘、除。

(3)16个按键的功能划分:

数字键:0-9;

功能键:加法键、减法键、乘法键、除法键、等于键、复位键

发挥部分:

能进行浮点小数的输入及运算。

 

2. 硬件设计

2.1 51单片机最小系统

  51单片机最小系统是指能使单片机正常工作的最简电路,如图2.1所示,其中大体包括三个部分:

  1. AT89C51单片机;
  2. 晶振电路模块;
  3. 复位电路模块。

图2.1 51单片机最小系统

2.1.1 AT89C51单片机

  AT89C51是一种带4K字节FLASH存储器的低电压、高性能CMOS 8位微处理器。如图2.1.1所示,AT89C51有40个引脚,32 个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。

  AT89C51 提供以下标准功能:4k 字节Flash 闪速存储器,256字节片内数据存储器(00H -7FH为片内RAM,80H-FFH为特殊功能寄存器SFR),32 个I/O 口线,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。同时,AT89C51可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。掉电方式保存RAM中的内容,但振荡器停止工作并禁止其它所有部件工作直到下一个硬件复位。

图2.1.1 AT89C51单片机 

2.1.2 晶振电路模块

  如图2.1.2所示,该模块由一个12MHz的晶振和两个30pF的电容构成,其中晶振的作用是产生一个稳定的时钟信号,而电容的作用则是将晶振中一些无用的高频信号过滤掉,提高整个模块工作的稳定性。

  该模块的主要用途有两个:

(1)为单片机的正常工作提供一个稳定的工作时序;

(2)为定时器的定时提供一个准确的脉冲信号,本次实习共使用了两个定时器,其中定时器0设置在了工作模式1,初值为60536,用于每隔5ms执行一次数码管的动态显示工作;而定时器1也设置在了工作模式1,初值为15536,同时外加变量T1_NUM的循环迭代,用于每隔500ms令数码管的某一位片选取反,从而达到闪烁的目的。

图2.1.2 晶振电路模块

2.1.3 复位电路模块

  如图2.1.3所示,该模块由一个按钮,一个电容和一个电阻构成,其中电容与电阻构成了一个RC的充电回路,当通电的一瞬间,由于电容两端电压无法瞬间突变,因此RST会在大概50ms的时间内保持高电平,50ms之后RST上的电平则可认为是低电平,这样就能达到上电复位并使单片机正常工作的作用。

  同时,在电容的两端还外加了一个轻触按钮,当按下该按钮时,RST上的电平则会重新变为高电平,让单片机复位,而当松开该按钮后,由于电容的充电作用,RST上的电平则会重新置为低电平,单片机正常工作。

图2.1.1 复位电路模块 

 

2.2 矩阵键盘模块

  如图2.2所示,该模块由16个轻触按钮构成,其中同一行的按钮的一端都相连,同一列的按钮的一端也相连。在编程时采用行输出,列输入的方法将按键的列信息读入后;再采用列输出,行输入的方法将按键的行信息也读入后,便可得知此刻是哪一个键被按下了。

图2.2 矩阵键盘模块

  此外,如表2.2所示,特别说明一下本次矩阵键盘的按键布局。此次矩阵键盘共有16个键,其中有10个为数字键入键,另外6个均为功能键,下面对其各自的用途进行简单的说明:

  1. C:全部清零键。按下该键后计算器将清零一切信息。
  2. CE:单个撤回键。按下该键后将向前撤回一个数字或者运算符。
  3. ".":小数点。按下该键后,编辑位的前一位将会加上一个小数点,而单片机在进行运算时,将会进行浮点运算。
  4. Operator:运算符。按下该键后运算符将会从"+ - × ÷"这四个运算符中循环替换。
  5. Confirm:运算符确认键。按下该键后则代表已确认运算符的选择,则数码管会清零,便于下一个运算数的输入。
  6. "=":等于号。等于按下该键后,单片机将会执行运算并显示结果。

表2.2 矩阵键盘布局

7

8

9

C

4

5

6

.

1

2

3

Operator

CE

0

Confirm

=

 

2.3 数码管显示模块

  如图2.3所示,该模块由两个四位的七段共阴极数码管构成,其中段选位为高电平有效,片选位为低电平有效,另外该模块还需特别注意,由于P0口在不加上拉电阻之前是没有任何驱动能力的,因此在连接此模块时,P0口一定要外加上拉电阻。

  该模块的主要用途是用于显示矩阵键盘所按下的键值,以及最后计算的结果。

图2.3 数码管显示模块

 

3. 软件设计(汇编)

3.1 变量的定义

  由于本次程序定义的变量较多,所以在介绍各函数之前,先说明一下每个变量的作用和用途。

  表3.1.1为用于浮点型运算所定义的变量。

表3.1.1

定义的变量名

地址

备注

NUM1_EXPONENT

030H

浮点数1的指数位

NUM1_MANTISSA1

031H

浮点数1的尾数位

NUM1_MANTISSA2

032H

NUM1_MANTISSA3

033H

NUM2_EXPONENT

034H

浮点数2的指数位

NUM2_MANTISSA1

035H

浮点数2的尾数位

NUM2_MANTISSA2

036H

NUM2_MANTISSA3

037H

SUM_EXPONENT

038H

结果的指数位

SUM_MANTISSA1

039H

结果的尾数位

SUM_MANTISSA2

03AH

SUM_MANTISSA3

03BH

NUM1_DECIMAL_L

03CH

运算数1小数部分

NUM1_DECIMAL_H

03DH

NUM2_DECIMAL_L

03EH

运算数2小数部分

NUM2_DECIMAL_H

03FH

  表3.1.2为用于使矩阵键盘和数码管正常工作所定义的变量。

表3.1.2

定义的变量名

地址

备注

DELAY1

041H

用于延时函数的循环迭代

DELAY2

042H

DELAY3

043H

T1_NUM

044H

用于扩展定时器1的定时时间

LED_NUM

045H

用于控制数码管每一次显示时打开该位片选的时间

LED_CS

046H

用于记录数码管每一次显示时需打开的片选

TWINKLE

047H

用于记录数码管目前闪烁的位置

KEY_X

048H

用于记录当前按键的行信息

KEY_Y

049H

用于记录当前按键的列信息

KEY_XY

04AH

用于记录当前按键的位置,由行信息与列信息按位相与而成

  表3.1.3为用于记录按键所输入的数及运算数1和运算数2所定义的变量。

表3.1.3 

定义的变量名

地址

备注

DECIADD

04EH

用于记录小数点在数码管上的地址

OPERADD

04FH

用于记录运算符在数码管上的地址

KEYADD

050H

用于记录当前需显示的键值在数码管上的地址

KEYNUM1

051H

数码管上的第一个数

KEYNUM2

052H

数码管上的第二个数

KEYNUM3

053H

数码管上的第三个数

KEYNUM4

054H

数码管上的第四个数

KEYNUM5

055H

数码管上的第五个数

KEYNUM6

056H

数码管上的第六个数

KEYNUM7

057H

数码管上的第七个数

KEYNUM8

058H

数码管上的第八个数

NUM1_LOW

059H

运算数1

NUM1_HIGH

05AH

NUM2_LOW

05BH

运算数2

NUM2_HIGH

05CH

  表3.1.4为用于双字节移位乘法和双字节移位除法所定义的变量。

表3.1.4  

定义的变量名

地址

备注

MULTI1_LOW

060H

乘数1

MULTI1_HIGH

061H

MULTI2_LOW

062H

乘数2

MULTI2_HIGH

063H

ADDEND_LOW

064H

加数

ADDEND_HIGH

065H

PRODUCT_LOW

066H

PRODUCT_HIGH

067H

DIVIDEND_LOW

068H

被除数

DIVIDEND_HIGH

069H

DIVISOR_LOW

06AH

除数

DIVISOR_HIGH

06BH

QUOTIENT_LOW

06CH

QUOTIENT_HIGH

06DH

REMAINDER_LOW

06EH

余数

REMAINDER_HIGH

06FH

  表3.1.5最主要为用于将十进制输入转化为二进制数据和将二进制数据转化为十进制输出所定义的变量。

表3.1.5

定义的变量名

地址

备注

POSITION_DEC

070H

用于记录十进制数每一位数所在的位置,方便加权求和用

POSITION_BIN

071H

用于记录二进制数每一位数所在的位置,方便加权求和用

LEN_RESULT

072H

用于记录输出结果的长度

LEN_NUM

073H

用于记录被除数左移的次数

POPDATA

074H

用于暂存出栈数据

OPERATOR_MOMENT

075H

用于记录临时的运算符,最主要用于改变运算符的显示

OPERATOR

076H

用于记录最终确定的运算符

KEYNUM_LAST

077H

用于记录上次显示的字符

FLAG_NEGATIVE

078H

用于决定输出结果是否需要输出负号

FLAG_FLOAT

079H

用于决定运算方式是否采用浮点运算

LEN1_DECIMAL

07AH

用于记录运算数1小数部分的长度,决定了下面比较值的大小

LEN2_DECIMAL

07BH

用于记录运算数2小数部分的长度,决定了下面比较值的大小

NUM1_DECI_COMP

07CH

用于记录运算数1转浮点型时小数部分需要比较的值

NUM2_DECI_COMP

07DH

用于记录运算数2转浮点型时小数部分需要比较的值

 

3.2 中断程序

  本次程序共使用了两个中断源,一是定时器0,二是定时器1,其中定时器0用于每隔5ms动态显示一次数码管,定时器1用于每隔1s闪烁一次数码管的某一位。

3.2.1 定时器0中断

  当定时器0产生中断时,第一步工作是将所用到的A累加器及工作寄存器中所用到的值放于堆栈中并对定时器0赋初值,其后调用数码管显示函数,流程图如图3.2.1所示,通过在一个极短的间隔内依次选通一个数码管并显示对应的值,从而产生视觉暂留现象,使我们在同一时间内能看到八个数码管所显示的不同的值。最后在完成函数的调用后将堆栈中的内容弹出,并返回主函数。

图3.2.1 数码管显示函数流程图

3.2.2 定时器1中断

  当定时器1产生中断时,同样压栈、赋初值,并在第10次进中断时,用"按位与"和"按位或"的方法取反闪烁位,最后出栈,返回主函数。

 

3.3 主函数

  程序在一开始会进行一些初始化的设置,其中包括设置堆栈指针,以及定义定时器工作方式,打开中断和定时器,在完成这些工作后,程序即会进入主函数,如图3.3所示,在程序进入主函数后,会一直循环判断是否有键按下,且按下的键值为多少,该进行何种操作及运算。

图3.3 主函数流程图

3.3.1 矩阵键盘的读取

  在经过20ms的延时去抖函数后,若仍有按键被按下,则程序会调用并执行该函数,该函数的流程图如图3.3.1所示,函数会通过行输出,列输入的方法读取矩阵键盘的列信息,再通过列输入,行输出的方法读取矩阵键盘的行信息,再通过"按位与"的方法,将两者组合为按键位置的信息,当使用者松手后,则立刻执行查表程序并得知该按键所需显示的数值后,即可返回主函数并执行下一步的功能。

图3.3.1 矩阵键盘的读取函数流程图

3.3.2 存储运算数

  当判断到有运算符或等于号的输入时,则意味着运算数1或运算数2已经输入完成,则程序会调用并执行该函数,如图3.3.2所示,程序会先清零运算数1或运算数2,并通过地址指针的方式,依次向前取数再乘以相应的10的指数并与其相加,从而得到所输入的运算数1或运算数2的真实值。

  其中,若运算数为负数,则将储存其补数;若运算数为小数,则将其分为整数部分和小数部分两部分,分别储存。

图3.3.2 存储运算数函数流程图

3.3.3 显示结果

  当运算操作完成后,程序会将所得结果送入运算数1中,并调用和执行该函数。如图3.3.3所示,程序会首先判断运算数1的正负,若为负数,则先在数码管的第一位显示负号,并取其补数覆盖原有的运算数1,后与正数的操作相同。

  正数的操作为:将运算数1除以10,令商覆盖原有的运算数1并求其余数,并使用PUSH指令,使其余数放于堆栈当中,然后依次循环此操作,直到运算数1除以10的结果为0,则跳出循环,将刚才放入堆栈中的数依次取出给到数码管的当前位进行显示,直至堆栈中的数完全取出。

  最后判断小数标志位是否为1,若为1,则清零标志位,显示小数点,并将小数部分的结果给到运算数1,后重复上述步骤,用于显示小数部分的结果。

图3.3.3 显示结果函数流程图

3.3.4 双字节移位乘法运算

  由于此次的任务需要进行0~9999的运算,所以编程中需要用双字节来扩充运算数的存储,因而无法使用已给的单字节乘法运算的指令,因此需要根据乘法计算的原理,自行编写双字节移位乘法运算的函数。如图3.3.4所示,双字节移位乘法的步骤如下:首先清零积和计数n(其中计数n用于记录运算数2右移的次数,当运算数2右移向外溢出16次时,则意味着该函数运算完成),然后右移运算数2,使其最低位溢出给C,并自增n,再判断C的值,若C为1,则意味着运算数1需左移n次,并把结果与积相加;若为0,则不进行任何操作,如是循环16次,即可得到最后的积。

图3.3.4 双字节移位乘法函数流程图

3.3.5 双字节移位除法运算

  由于此次的任务需要进行0~9999的运算,所以编程中需要用双字节来扩充运算数的存储,因而无法使用已给的单字节除法运算的指令,因此需要根据除法计算的原理,自行编写双字节移位除法运算的函数。如图3.3.5所示,双字节移位乘法的步骤如下:首先清零被除数,然后左移运算数1,使其溢出一位给到被除数,并判断此时的被除数大于或等于除数吗,若大于或等于,则先将被除数减去除数,并置位C且左移商使其放于商的最低位中;否则,清零C并左移商使其放于商的最低位中。如是循环16次,并把此时的被除数的结果给到余数,即可得到运算数1除以运算数2的商和余数。

图3.3.5 双字节移位除法函数流程图

3.3.6 负数乘除法运算

  在计算机的存储中,负数是通过取其补数的方法来存储的,而在实际的运算中,补数的加减也确实满足实际的结果,但是在乘除的运算中,却只有正数乘以负数是满足的,其他情况下都不满足实际的结果,因此在乘除的运算当中,需将负数转化为正数来进行运算,再通过运算数负号的个数来判断最后的结果为负还是为正,流程图如图3.3.6所示。

图3.3.6 负数乘除法流程图

3.2.7 浮点型加法运算

  浮点型的加法运算是本次任务的重点工作。此工作共包含三部分:

  (1)将所输入的小数转化为浮点型的存储格式存储起来;

  (2)将所输入的两个浮点型小数通过浮点型相加的函数相加;

  (3)将所得到的结果转换为10进制的方式输出于数码管。

(1)转换为浮点型存储格式

  首先介绍的是第一步,即把所输入的小数转化为浮点型的存储格式存储起来。如图3.2.7.1所示,首先将运算数的整数部分放入浮点型存储格式中的尾数位的后两个字节当中,其后将浮点型存储格式中的指数部分置为151,其原因是,整数部分在尾数位的左边时所对应的指数部分应该是127,而将其放于尾数位的后两个字节中,也就相当于将整数部分向右移动了24位,因此127+24=151,此时的指数部分为151。

  然后左移小数部分的值并判断这个值是否大于所比较的值(关于所比较的值,以下做个简单说明:若小数位中的值为一位数,即6,则意味着此时的小数为0.6,则所比较的值应为10;若小数位中的值为两位数,即66,则意味着此时的小数为0.66,则所比较的值为100,若小数位中的值为三位数时,以此类推,所比较的值应为1000),若大于或等于则小数部分的值减去所比较的值,并置位C且同时左移尾数放于尾数的最低位中,指数位减1;若小于,则直接清零C且同时左移尾数放于尾数的最低位中,指数位减1。重复以上操作,直到尾数位左移产生的溢出位为1,则按照浮点型存储的格式,此时还应将整个四字节的浮点型存储数整体向右移一位。

图3.2.7.1 转换为浮点型存储格式流程图

(2)浮点型相加函数

  其次介绍的是第二步,即把所输入的两个浮点型小数通过浮点型相加的函数将其相加。如图3.2.7.2所示,首先应将指数位与尾数位通过左移和"按位或"运算的方法分离开来,由于这个步骤不是重点,因此以下流程图将其省略,其次取两者中指数位较大的一方为结果的指数位,则指数位较小的一方,需通过右移尾数的方法使其指数位的值增大直至与另一方的指数位相等,则令两数的尾数相加,最后判断相加的尾数位是否存在进位现象,若存在的话,则尾数位右移一位,指数位加一,若不存在的话则完成浮点型的加法运算。

图3.2.7.2 浮点型相加函数流程图

(3)转换为十进制方式输出

  最后介绍的是第三步,即把浮点型运算的结果转换为十进制的方式输出于数码管。如图3.2.7.3所示,首先通过不断左移尾数位取出整数部分,若指数部分原本便小于127,则右移尾数位为之后小数部分的输出做好准备。取出整数部分后则可调用显示结果函数将其显示了,其后再加上小数点并取出小数部分,在此规定小数部分最多只显示三位,即加数为取整,其中n为尾数位左移的次数,最后再将小数部分显示出来,即可完成浮点型加法运算。

图3.2.7.3 转换为十进制方式输出流程图

 

4. 仿真结果

4.1 加法运算仿真结果

图4.1.1 加数1

图4.1.2 加数2

图4.1.3 加法运算仿真结果

4.2 减法运算仿真结果

图4.2.1 被减数

图4.2.2 减数

图4.2.3 减法运算仿真结果

4.3 乘法运算仿真结果

图4.3.1 乘数1

图4.3.2 乘数2

图4.3.3 乘法运算仿真结果

4.4 除法运算仿真结果

图4.4.1 被除数

图4.4.2 除数

图4.4.3 除法运算仿真结果

4.5 负数乘法仿真结果

图4.5.1 乘数1

图4.5.2 乘数2

图4.5.3 负数乘法仿真结果

4.6 负数除法仿真结果

图4.6.1 被除数

图4.6.2 除数

图4.6.3 负数除法仿真结果

4.7 浮点加法仿真结果

图4.7.1 小数1

图4.7.2 小数2

图4.7.3 浮点加法仿真结果

 

附录

源程序代码

   1 KEY                EQU     P1
   2 LED                EQU     P3
   3 LUMINANCE          EQU     50
   4 ON_OFF             EQU     008H
   5 NUM1ADD            EQU     051H
   6 NUM8ADD            EQU     058H
   7     
   8 NUM1_EXPONENT      DATA    030H;浮点运算数1
   9 NUM1_MANTISSA1     DATA    031H;
  10 NUM1_MANTISSA2     DATA    032H;
  11 NUM1_MANTISSA3     DATA    033H;
  12 NUM2_EXPONENT      DATA    034H;浮点运算数2
  13 NUM2_MANTISSA1     DATA    035H;
  14 NUM2_MANTISSA2     DATA    036H;
  15 NUM2_MANTISSA3     DATA    037H;
  16 SUM_EXPONENT       DATA    038H;浮点和
  17 SUM_MANTISSA1      DATA    039H;
  18 SUM_MANTISSA2      DATA    03AH;
  19 SUM_MANTISSA3      DATA    03BH;
  20 NUM1_DECIMAL_L     DATA    03CH;运算数1小数部分
  21 NUM1_DECIMAL_H     DATA    03DH;
  22 NUM2_DECIMAL_L     DATA    03EH;运算数2小数部分
  23 NUM2_DECIMAL_H     DATA    03FH;
  24 
  25 DELAY1             DATA    041H;
  26 DELAY2             DATA    042H;
  27 DELAY3             DATA    043H;延时时间
  28 T1_NUM             DATA    044H;定时时间
  29 LED_NUM            DATA    045H;LED亮度
  30 LED_CS             DATA    046H;LED片选
  31 TWINKLE            DATA    047H;闪烁位置
  32 KEY_X              DATA    048H;键盘行信息
  33 KEY_Y              DATA    049H;键盘列信息
  34 KEY_XY             DATA    04AH;按键位置
  35 
  36 DECIADD            DATA    04EH;小数点地址
  37 OPERADD            DATA    04FH;运算符地址    
  38 KEYADD             DATA    050H;当前键值地址
  39 KEYNUM1            DATA    051H;第1次键值
  40 KEYNUM2            DATA    052H;第2次键值
  41 KEYNUM3            DATA    053H;第3次键值
  42 KEYNUM4            DATA    054H;第4次键值
  43 KEYNUM5            DATA    055H;第5次键值
  44 KEYNUM6            DATA    056H;第6次键值
  45 KEYNUM7            DATA    057H;第7次键值
  46 KEYNUM8            DATA    058H;第8次键值
  47 NUM1_LOW           DATA    059H;运算数1低八位
  48 NUM1_HIGH          DATA    05AH;运算数1高八位
  49 NUM2_LOW           DATA    05BH;运算数2低八位
  50 NUM2_HIGH          DATA    05CH;运算数2高八位
  51 
  52 MULTI1_LOW         DATA    060H;乘数1的低八位
  53 MULTI1_HIGH        DATA    061H;乘数1的高八位
  54 MULTI2_LOW         DATA    062H;乘数2的低八位
  55 MULTI2_HIGH        DATA    063H;乘数2的高八位
  56 ADDEND_LOW         DATA    064H;加数的低八位
  57 ADDEND_HIGH        DATA    065H;加数的高八位
  58 PRODUCT_LOW        DATA    066H;积的低八位
  59 PRODUCT_HIGH       DATA    067H;积的高八位
  60 DIVIDEND_LOW       DATA    068H;被除数的低八位
  61 DIVIDEND_HIGH      DATA    069H;被除数的高八位
  62 DIVISOR_LOW        DATA    06AH;除数的低八位
  63 DIVISOR_HIGH       DATA    06BH;除数的高八位
  64 QUOTIENT_LOW       DATA    06CH;商的低八位
  65 QUOTIENT_HIGH      DATA    06DH;商的高八位
  66 REMAINDER_LOW      DATA    06EH;余数的低八位
  67 REMAINDER_HIGH     DATA    06FH;余数的高八位
  68 
  69 POSITION_DEC       DATA    070H;位置(十进制)
  70 POSITION_BIN       DATA    071H;位置(二进制)
  71 LEN_RESULT         DATA    072H;结果长度
  72 LEN_NUM            DATA    073H;运算数长度
  73 POPDATA            DATA    074H;出栈数据
  74 OPERATOR_MOMENT    DATA    075H;临时运算符
  75 OPERATOR           DATA    076H;运算符
  76 KEYNUM_LAST        DATA    077H;上一次键值
  77 FLAG_NEGATIVE      DATA    078H;负数标志位
  78 FLAG_FLOAT         DATA    079H;浮点标志位
  79 LEN1_DECIMAL       DATA    07AH;NUM1小数位长度
  80 LEN2_DECIMAL       DATA    07BH;NUM2小数位长度
  81 NUM1_DECI_COMP     DATA    07CH;NUM1小数位的比较数
  82 NUM2_DECI_COMP     DATA    07DH;NUM2小数位的比较数
  83 
  84 ORG 0000H
  85 JMP    MAIN
  86 ORG 0003H
  87 JMP    INT_EX0
  88 ORG 000BH
  89 JMP    INT_TIMER0
  90 ORG 0013H
  91 JMP    INT_EX1
  92 ORG 001BH
  93 JMP    INT_TIMER1
  94 ORG 0023H
  95 JMP    INT_UART
  96 
  97 ORG 0030H
  98 MAIN:        
  99         MOV SP,#008H;堆栈指针
 100         ACALL CLEAR;所有数据清零
 101         MOV LED_NUM,#LUMINANCE;LED亮度
 102         
 103         ;定时器初始化
 104         MOV TMOD,#011H;16位工作方式1
 105         MOV TH0,#0ECH;数码管动态显示用
 106         MOV TL0,#078H;初值为60536
 107         MOV TH1,#03CH;数码管闪烁用
 108         MOV TL1,#0B0H;初值为15536
 109         MOV T1_NUM,#10;定时50*10=500MS
 110         SETB EA
 111         SETB ET0
 112         SETB ET1
 113         SETB TR0
 114         SETB TR1
 115             
 116 JUDGE_PR:
 117         MOV KEY,#0F0H;读高四位
 118         MOV A,KEY
 119         CJNE A,#0F0H,COMFIRM_PR
 120         JMP JUDGE_PR
 121 COMFIRM_PR:
 122         ACALL DELAY;软件去抖
 123         MOV KEY,#00FH;读低四位
 124         MOV A,KEY
 125         CJNE A,#00FH,OPERATE
 126         JMP JUDGE_PR
 127 OPERATE:
 128         ACALL KEY_READ
 129         MOV R0,KEYADD
 130         MOV A,@R0
 131 ;---左移---;
 132 K0A:
 133         CJNE A,#00AH,K0B
 134         ;恢复历史值        
 135         MOV R0,KEYADD
 136         MOV @R0,KEYNUM_LAST
 137         ;调用左移函数    
 138         ACALL LEFT
 139         JMP    JUDGE_PR
 140 ;---右移---;
 141 K0B:
 142         CJNE A,#00BH,K0C
 143         ;恢复历史值        
 144         MOV R0,KEYADD
 145         MOV @R0,KEYNUM_LAST
 146         ;下划线则清零
 147         CJNE @R0,#00AH,SKIP_ZERO
 148         MOV @R0,#000H
 149 SKIP_ZERO:
 150         ;调用右移函数
 151         ACALL RIGHT
 152         JMP    JUDGE_PR
 153 ;---清零---;
 154 K0C:
 155         CJNE A,#00CH,K0D
 156         ACALL CLEAR
 157         MOV OPERATOR,#000H;无任何运算符
 158         MOV OPERATOR_MOMENT,#000H;无任何运算符
 159         JMP    JUDGE_PR
 160 ;---浮点---;
 161 K0D:
 162         CJNE A,#00DH,K0E
 163         ACALL POINT
 164         JMP    JUDGE_PR
 165 ;---等于---;
 166 K0E:
 167         CJNE A,#00EH,K0F
 168         ACALL EQUAL
 169         JMP    JUDGE_PR
 170 ;---运算符---;
 171 K0F:
 172         CJNE A,#00FH,K10
 173         ACALL SAVENUM1
 174 
 175         INC OPERATOR_MOMENT
 176         MOV A,OPERATOR_MOMENT
 177         CJNE A,#005H,K0F_NEXT;超过4则为1
 178         MOV OPERATOR_MOMENT,#001H
 179 ;改变显示内容
 180 K0F_NEXT:
 181         MOV A,OPERATOR_MOMENT
 182         MOV R0,KEYADD
 183         ADD A,@R0
 184         MOV @R0,A
 185 K0F_END:
 186         JMP    JUDGE_PR
 187 ;---错误---;
 188 K10:
 189         CJNE A,#010H,OPERATE_END
 190         ACALL FAULT
 191 ;---结束---;
 192 OPERATE_END:
 193         MOV A,KEYADD;超过NUM8则将停在该位
 194         CJNE A,#NUM8ADD,PREPARE_NEXT
 195         JMP JMP_LOOP
 196 PREPARE_NEXT:
 197         ;片选右移
 198         MOV A,LED_CS
 199         CLR C
 200         RRC A
 201         MOV LED_CS,A
 202         ;闪烁右移
 203         MOV A,TWINKLE
 204         CLR C
 205         RRC A
 206         MOV TWINKLE,A
 207         ;地址加一
 208         INC KEYADD
 209         ;下一位显示下划线
 210         MOV R0,KEYADD
 211         MOV @R0,#00AH;显示下划线
 212 JMP_LOOP:
 213         JMP    JUDGE_PR
 214 
 215 ;--------左移功能--------;
 216 LEFT:
 217         MOV A,KEYADD;小于NUM1则无法左移
 218         CJNE A,#NUM1ADD,STATR_LEFT
 219         JMP LEFT_END
 220 STATR_LEFT:
 221         ;片选左移
 222         MOV A,LED_CS
 223         SETB C
 224         RLC A
 225         MOV LED_CS,A
 226         ;闪烁左移
 227         MOV A,TWINKLE
 228         CLR C
 229         RLC A
 230         MOV TWINKLE,A
 231         ;地址减一
 232         DEC KEYADD
 233         ;下一位显示下划线
 234         MOV R0,KEYADD
 235         MOV @R0,#00AH;显示下划线
 236 LEFT_END:
 237         RET
 238 
 239 ;--------右移功能--------;
 240 RIGHT:
 241         MOV A,KEYADD;超过NUM8则为无法右移
 242         CJNE A,#NUM8ADD,START_RIGHT
 243         JMP RIGHT_CLEAR
 244 START_RIGHT:
 245         ;片选右移
 246         MOV A,LED_CS
 247         CLR C
 248         RRC A
 249         MOV LED_CS,A
 250         ;闪烁右移
 251         MOV A,TWINKLE
 252         CLR C
 253         RRC A
 254         MOV TWINKLE,A
 255         ;地址加一
 256         INC KEYADD
 257         ;下一位显示下划线
 258         MOV R0,KEYADD
 259         MOV @R0,#00AH;显示下划线
 260         MOV A,OPERADD
 261         CJNE A,#051H,RIGHT_CLEAR
 262         JMP RIGHT_END
 263 RIGHT_CLEAR:
 264         MOV OPERATOR,OPERATOR_MOMENT
 265         ACALL CLEAR;所有数据清零
 266 RIGHT_END:
 267         MOV OPERATOR_MOMENT,#000H
 268         RET
 269 
 270 ;--------所有数据清零--------;
 271 CLEAR:
 272         MOV KEYNUM1,#00AH;显示下划线
 273         ;MOV KEYNUM2,#000H;数据清零
 274         ;MOV KEYNUM3,#000H;数据清零
 275         ;MOV KEYNUM4,#000H;数据清零
 276         ;MOV KEYNUM5,#000H;数据清零
 277         ;MOV KEYNUM6,#000H;数据清零
 278         ;MOV KEYNUM7,#000H;数据清零
 279         ;MOV KEYNUM8,#000H;数据清零
 280         ;MOV NUM1_LOW,#000H;运算数1清零
 281         ;MOV NUM2_LOW,#000H;运算数2清零
 282         ;MOV OPERATOR,#000H;无任何运算符
 283         MOV KEYADD,#NUM1ADD;当前键值地址为第1个
 284         MOV LED_CS,#07FH;显示第一位
 285         MOV TWINKLE,#080H;第一位闪烁
 286         
 287         RET
 288         
 289 ;--------浮点运算--------;
 290 POINT:
 291         DEC KEYADD
 292         MOV R0,KEYADD
 293         MOV A,@R0
 294         ADD A,#020H
 295         MOV @R0,A
 296         ;地址加一
 297         INC KEYADD
 298         ;下一位显示下划线
 299         MOV R0,KEYADD
 300         MOV @R0,#00AH;显示下划线
 301         RET
 302 
 303 ;--------存储运算数1--------;
 304 SAVENUM1:
 305 ;求运算数1初始化
 306 INIT_NUM1:
 307         MOV R0,KEYADD;当前键值地址
 308         MOV OPERADD,KEYADD;运算符地址
 309         MOV POSITION_DEC,#000H;位置(个十百)
 310         MOV NUM1_LOW,#000H;运算数1低八位
 311         MOV NUM1_HIGH,#000H;运算数1高八位
 312         MOV FLAG_FLOAT,#000H;清零浮点标志位
 313 ;判断是否为第一个数
 314 JUDGE_FIRST:
 315         CJNE R0,#NUM1ADD,RESULT_NUM1
 316         JMP SAVENUM1_END
 317 ;求运算数1结果
 318 RESULT_NUM1:
 319         DEC R0
 320 ;判断浮点
 321 NUM1_FLOAT:
 322         MOV A,@R0
 323         CJNE A,#01FH,NUM1F_NEQ
 324 NUM1F_EQ:
 325         ;等于则直接跳过
 326         JMP NUM1_NEGATIVE
 327 NUM1F_NEQ:
 328         ;小于则直接跳过
 329         JC NUM1_NEGATIVE
 330         ;储存小数点的位置
 331         MOV DECIADD,R0
 332         ;NUM1中储存了小数位
 333         MOV NUM1_DECIMAL_L,NUM1_LOW
 334         MOV NUM1_DECIMAL_H,NUM1_HIGH
 335         MOV LEN1_DECIMAL,POSITION_DEC
 336         ;让NUM1储存整数位
 337         MOV POSITION_DEC,#000H;位置(个十百)
 338         MOV NUM1_LOW,#000H;运算数1低八位
 339         MOV NUM1_HIGH,#000H;运算数1高八位
 340         ;个位数正常化
 341         MOV A,@R0
 342         CLR C
 343         SUBB A,#020H
 344         MOV @R0,A
 345         ;浮点标志位置一
 346         MOV FLAG_FLOAT,#001H
 347         JMP NUM1_POSITIVE
 348 ;判断负号
 349 NUM1_NEGATIVE:
 350         MOV A,@R0
 351         CJNE A,#011H,NUM1_POSITIVE
 352         JMP NUM1_TRANSFORM
 353 ;正数操作
 354 NUM1_POSITIVE:
 355         INC POSITION_DEC
 356         MOV MULTI1_LOW,@R0
 357         MOV MULTI1_HIGH,#0
 358         MOV MULTI2_LOW,#10
 359         MOV MULTI2_HIGH,#0
 360         MOV R3,POSITION_DEC
 361         ;R2为1直接相加,不用相乘
 362         DJNZ R3,ACTUAL_VALUE1
 363         MOV PRODUCT_LOW,MULTI1_LOW
 364         MOV PRODUCT_HIGH,MULTI1_HIGH
 365         JMP    WEIGHTED_SUM1
 366 ;该位实际代表值
 367 ACTUAL_VALUE1:
 368         ACALL MULTIPLY
 369         MOV MULTI1_LOW,PRODUCT_LOW
 370         MOV MULTI1_HIGH,PRODUCT_HIGH
 371         MOV MULTI2_LOW,#10
 372         MOV MULTI2_HIGH,#0
 373         DJNZ R3,ACTUAL_VALUE1
 374 WEIGHTED_SUM1:
 375         ;低位加权求和
 376         MOV A,NUM1_LOW
 377         ADD A,PRODUCT_LOW
 378         MOV NUM1_LOW,A
 379         ;高位加权求和
 380         MOV A,NUM1_HIGH
 381         ADDC A,PRODUCT_HIGH
 382         MOV NUM1_HIGH,A
 383         CJNE R0,#NUM1ADD,RESULT_NUM1
 384         JMP SAVENUM1_END
 385 NUM1_TRANSFORM:
 386         ;NUM1取反
 387         MOV A,NUM1_LOW
 388         CPL A
 389         MOV NUM1_LOW,A
 390         MOV A,NUM1_HIGH
 391         CPL A
 392         MOV NUM1_HIGH,A
 393         ;NUM1加一
 394         MOV A,NUM1_LOW
 395         ADD A,#1
 396         MOV NUM1_LOW,A
 397         MOV A,NUM1_HIGH
 398         ADDC A,#0
 399         MOV NUM1_HIGH,A
 400 SAVENUM1_END:
 401         ;恢复小数点
 402         MOV R0,DECIADD
 403         MOV A,@R0
 404         ADD A,#020H
 405         MOV @R0,A
 406         RET
 407 
 408 ;--------显示结果--------;
 409 EQUAL:
 410 ;调试用
 411         ;MOV FLAG_FLOAT,#01H;小数标志位置一
 412         ;MOV OPERATOR,#01H;运算符为加法
 413 ;求运算数2初始化(只用改地址就好了)
 414 INIT_NUM2:
 415         MOV R0,KEYADD;当前键值地址
 416         MOV POSITION_DEC,#000H;位置(个十百)
 417         MOV NUM2_LOW,#000H;运算数2低八位
 418         MOV NUM2_HIGH,#000H;运算数2高八位
 419         INC OPERADD;运算数2最高位地址
 420 ;求运算数2结果
 421 RESULT_NUM2:
 422         DEC R0
 423 ;判断浮点
 424 NUM2_FLOAT:
 425         MOV A,@R0
 426         CJNE A,#01FH,NUM2F_NEQ
 427 NUM2F_EQ:
 428         ;等于则直接跳过
 429         JMP NUM2_POSITIVE
 430 NUM2F_NEQ:
 431         ;小于则直接跳过
 432         JC NUM2_POSITIVE
 433         ;NUM2中储存了小数位
 434         MOV NUM2_DECIMAL_L,NUM2_LOW
 435         MOV NUM2_DECIMAL_H,NUM2_HIGH
 436         MOV LEN2_DECIMAL,POSITION_DEC
 437         ;让NUM2储存整数位
 438         MOV POSITION_DEC,#000H;位置(个十百)
 439         MOV NUM2_LOW,#000H;运算数1低八位
 440         MOV NUM2_HIGH,#000H;运算数1高八位
 441         ;个位数正常化
 442         MOV A,@R0
 443         CLR C
 444         SUBB A,#020H
 445         MOV @R0,A
 446         ;浮点标志位置一
 447         MOV FLAG_FLOAT,#001H
 448         JMP NUM2_POSITIVE
 449 ;判断负号
 450 NUM2_NEGATIVE:
 451         MOV A,@R0
 452         CJNE A,#011H,NUM2_POSITIVE
 453         JMP NUM2_TRANSFORM
 454 ;正常操作
 455 NUM2_POSITIVE:
 456         INC POSITION_DEC
 457         MOV MULTI1_LOW,@R0
 458         MOV MULTI1_HIGH,#0
 459         MOV MULTI2_LOW,#10
 460         MOV MULTI2_HIGH,#0
 461         MOV R3,POSITION_DEC
 462         ;R2为1直接相加,不用相乘
 463         DJNZ R3,ACTUAL_VALUE2
 464         MOV PRODUCT_LOW,MULTI1_LOW
 465         MOV PRODUCT_HIGH,MULTI1_HIGH
 466         JMP    WEIGHTED_SUM2
 467 ;该位实际代表值
 468 ACTUAL_VALUE2:
 469         ACALL MULTIPLY
 470         MOV MULTI1_LOW,PRODUCT_LOW
 471         MOV MULTI1_HIGH,PRODUCT_HIGH
 472         MOV MULTI2_LOW,#10
 473         MOV MULTI2_HIGH,#0
 474         DJNZ R3,ACTUAL_VALUE2
 475 WEIGHTED_SUM2:
 476         ;低位加权求和
 477         MOV A,NUM2_LOW
 478         ADD A,PRODUCT_LOW
 479         MOV NUM2_LOW,A
 480         ;高位加权求和
 481         MOV A,NUM2_HIGH
 482         ADDC A,PRODUCT_HIGH
 483         MOV NUM2_HIGH,A
 484         MOV A,R0
 485         CJNE A,#NUM1ADD,RESULT_NUM2
 486         JMP OPERATOR_0
 487 NUM2_TRANSFORM:
 488         ;NUM1取反
 489         MOV A,NUM2_LOW
 490         CPL A
 491         MOV NUM2_LOW,A
 492         MOV A,NUM2_HIGH
 493         CPL A
 494         MOV NUM2_HIGH,A
 495         ;NUM1加一
 496         MOV A,NUM2_LOW
 497         ADD A,#1
 498         MOV NUM2_LOW,A
 499         MOV A,NUM2_HIGH
 500         ADDC A,#0
 501         MOV NUM2_HIGH,A
 502 
 503 ;运算操作
 504 OPERATOR_0:
 505         MOV A,OPERATOR
 506 OPERATOR_1:        
 507         CJNE A,#001H,OPERATOR_2
 508         ACALL PLUS
 509 OPERATOR_2:
 510         CJNE A,#002H,OPERATOR_3
 511         ACALL SUBTRACT        
 512 OPERATOR_3:
 513         CJNE A,#003H,OPERATOR_4
 514         MOV MULTI1_LOW,NUM1_LOW
 515         MOV MULTI1_HIGH,NUM1_HIGH
 516         MOV MULTI2_LOW,NUM2_LOW
 517         MOV MULTI2_HIGH,NUM2_HIGH
 518         ACALL MULTIPLY
 519         MOV NUM1_LOW,PRODUCT_LOW
 520         MOV NUM1_HIGH,PRODUCT_HIGH
 521 OPERATOR_4:
 522         CJNE A,#004H,CLEAR_DIS
 523         MOV DIVISOR_LOW,NUM2_LOW
 524         MOV DIVISOR_HIGH,NUM2_HIGH
 525         ACALL DIVIDE
 526 
 527 ;清零显示屏
 528 CLEAR_DIS:
 529         ACALL CLEAR;所有数据清零
 530         MOV OPERATOR,#000H;无任何运算符
 531         MOV OPERATOR_MOMENT,#000H;无任何运算符
 532 ;判断负数
 533 CONSULT_NEGATIVE:
 534         MOV FLAG_NEGATIVE,#0
 535         MOV A,NUM1_HIGH
 536         RLC A
 537         JNC DEC_OUTPUT
 538         MOV FLAG_NEGATIVE,#1
 539         ;NUM1取反
 540         MOV A,NUM1_LOW
 541         CPL A
 542         MOV NUM1_LOW,A
 543         MOV A,NUM1_HIGH
 544         CPL A
 545         MOV NUM1_HIGH,A
 546         ;NUM1加一
 547         MOV A,NUM1_LOW
 548         ADD A,#1
 549         MOV NUM1_LOW,A
 550         MOV A,NUM1_HIGH
 551         ADDC A,#0
 552         MOV NUM1_HIGH,A
 553         
 554 
 555 DEC_OUTPUT:
 556         MOV KEYADD,#NUM1ADD;当前键值地址为第1个
 557 ;转换为十进制输出
 558 CONVERSION_DEC:
 559         ;MOV NUM1_LOW,#1
 560         ;MOV NUM1_HIGH,#0
 561         MOV LEN_RESULT,#000H
 562 ;求余压栈
 563 REMAINDER:
 564         MOV DIVISOR_LOW,#10
 565         MOV DIVISOR_HIGH,#0
 566         ACALL DIVIDE
 567         PUSH REMAINDER_LOW
 568         INC LEN_RESULT
 569         MOV A,NUM1_HIGH
 570         JNZ REMAINDER
 571         MOV A,NUM1_LOW
 572         JNZ REMAINDER
 573 
 574 ;出栈显示
 575 OUT_RESULT:
 576         MOV A,FLAG_NEGATIVE
 577         JZ OUT_LOOP
 578         INC LEN_RESULT;显示长度加1
 579         MOV R0,KEYADD
 580         MOV @R0,#17;显示负号
 581         JMP OUT_NEXT
 582 OUT_LOOP:
 583         MOV R0,KEYADD
 584         POP POPDATA
 585         MOV @R0,POPDATA
 586 OUT_NEXT:
 587         INC KEYADD
 588         ;增加片选位
 589         MOV A,LED_CS
 590         CLR C
 591         RRC A
 592         MOV LED_CS,A
 593         ;右移闪烁位
 594         MOV A,TWINKLE
 595         CLR C
 596         RR A
 597         MOV TWINKLE,A
 598         DJNZ LEN_RESULT,OUT_LOOP
 599         
 600         ;判断小数标志位,是否需要显示小数
 601         MOV A,FLAG_FLOAT
 602         CJNE A,#001H,EQUAL_END1
 603         JMP DIS_DECIMAL
 604 EQUAL_END1:
 605         LJMP EQUAL_END
 606 DIS_DECIMAL:
 607         ;添加小数点
 608         DEC KEYADD
 609         MOV R0,KEYADD
 610         MOV A,@R0
 611         ADD A,#020H
 612         MOV @R0,A
 613         INC KEYADD
 614         ;求小数部分的显示值
 615         MOV NUM1_LOW,#000H;运算数2低八位
 616         MOV NUM1_HIGH,#000H;运算数2高八位
 617         ;左移尾数
 618         CLR C
 619         MOV A,SUM_MANTISSA1
 620         RLC    A
 621         MOV SUM_MANTISSA1,A
 622         JNC DECI_DIS2
 623         MOV NUM1_LOW,#244
 624         MOV NUM1_HIGH,#1
 625 DECI_DIS2:
 626         ;左移尾数
 627         CLR C
 628         MOV A,SUM_MANTISSA1
 629         RLC    A
 630         MOV SUM_MANTISSA1,A
 631         JNC DECI_DIS3
 632         MOV A,NUM1_LOW
 633         ADD A,#250
 634         MOV NUM1_LOW,A
 635         MOV A,NUM1_HIGH
 636         ADDC A,#0
 637         MOV NUM1_HIGH,A
 638 DECI_DIS3:
 639         ;左移尾数
 640         CLR C
 641         MOV A,SUM_MANTISSA1
 642         RLC    A
 643         MOV SUM_MANTISSA1,A
 644         JNC DECI_DIS4
 645         MOV A,NUM1_LOW
 646         ADD A,#125
 647         MOV NUM1_LOW,A
 648         MOV A,NUM1_HIGH
 649         ADDC A,#0
 650         MOV NUM1_HIGH,A
 651 DECI_DIS4:
 652         ;左移尾数
 653         CLR C
 654         MOV A,SUM_MANTISSA1
 655         RLC    A
 656         MOV SUM_MANTISSA1,A
 657         JNC DECI_DIS5
 658         MOV A,NUM1_LOW
 659         ADD A,#63
 660         MOV NUM1_LOW,A
 661         MOV A,NUM1_HIGH
 662         ADDC A,#0
 663         MOV NUM1_HIGH,A
 664 DECI_DIS5:
 665         ;左移尾数
 666         CLR C
 667         MOV A,SUM_MANTISSA1
 668         RLC    A
 669         MOV SUM_MANTISSA1,A
 670         JNC DECI_DIS6
 671         MOV A,NUM1_LOW
 672         ADD A,#31
 673         MOV NUM1_LOW,A
 674         MOV A,NUM1_HIGH
 675         ADDC A,#0
 676         MOV NUM1_HIGH,A
 677 DECI_DIS6:
 678         ;左移尾数
 679         CLR C
 680         MOV A,SUM_MANTISSA1
 681         RLC    A
 682         MOV SUM_MANTISSA1,A
 683         JNC DECI_DIS7
 684         MOV A,NUM1_LOW
 685         ADD A,#16
 686         MOV NUM1_LOW,A
 687         MOV A,NUM1_HIGH
 688         ADDC A,#0
 689         MOV NUM1_HIGH,A
 690 DECI_DIS7:
 691         ;左移尾数
 692         CLR C
 693         MOV A,SUM_MANTISSA1
 694         RLC    A
 695         MOV SUM_MANTISSA1,A
 696         JNC DECI_DIS8
 697         MOV A,NUM1_LOW
 698         ADD A,#8
 699         MOV NUM1_LOW,A
 700         MOV A,NUM1_HIGH
 701         ADDC A,#0
 702         MOV NUM1_HIGH,A
 703 DECI_DIS8:
 704         ;左移尾数
 705         CLR C
 706         MOV A,SUM_MANTISSA1
 707         RLC    A
 708         MOV SUM_MANTISSA1,A
 709         JNC DECI_DIS9
 710         MOV A,NUM1_LOW
 711         ADD A,#4
 712         MOV NUM1_LOW,A
 713         MOV A,NUM1_HIGH
 714         ADDC A,#0
 715         MOV NUM1_HIGH,A
 716 DECI_DIS9:
 717         ;MOV NUM1_LOW,#50
 718         MOV FLAG_FLOAT,#000H;清零小数标志位
 719         LJMP CONVERSION_DEC
 720 EQUAL_END:
 721         MOV R0,KEYADD
 722         MOV @R0,#00AH;显示下划线
 723         RET    
 724 
 725 ;--------双字节加法运算--------;
 726 PLUS:
 727 ;调试用
 728         ;MOV NUM1_LOW,#20
 729         ;MOV NUM1_HIGH,#0
 730         ;MOV NUM2_LOW,#30
 731         ;MOV NUM2_HIGH,#0
 732         ;MOV NUM1_DECIMAL_L,#5
 733         ;MOV NUM1_DECIMAL_H,#2
 734         ;MOV NUM2_DECIMAL_L,#20
 735         ;MOV NUM2_DECIMAL_H,#3
 736         ;MOV NUM1_LOW,NUM1_DECIMAL_L
 737         ;MOV NUM1_HIGH,NUM1_DECIMAL_H
 738         ;LJMP PLUS_END
 739         
 740         MOV A,FLAG_FLOAT
 741         JNZ PLUS_FLOAT
 742 PLUS_NORMAL:
 743         MOV A,NUM1_LOW
 744         ADD A,NUM2_LOW
 745         MOV NUM1_LOW,A
 746         MOV A,NUM1_HIGH
 747         ADDC A,NUM2_HIGH
 748         MOV NUM1_HIGH,A
 749         LJMP PLUS_END
 750 PLUS_FLOAT:
 751         MOV NUM1_EXPONENT,000H;清空浮点数1
 752         MOV NUM1_MANTISSA1,000H;
 753         MOV NUM1_MANTISSA2,000H;
 754         MOV NUM1_MANTISSA3,000H;
 755         MOV NUM2_EXPONENT,000H;清空浮点数2
 756         MOV NUM2_MANTISSA1,000H;
 757         MOV NUM2_MANTISSA2,000H;
 758         MOV NUM2_MANTISSA3,000H;
 759         MOV SUM_EXPONENT,000H;清空浮点加法结果
 760         MOV SUM_MANTISSA1,000H;
 761         MOV SUM_MANTISSA2,000H;
 762         MOV SUM_MANTISSA3,000H;
 763         MOV NUM1_DECI_COMP,001H;
 764         MOV NUM2_DECI_COMP,001H;
 765 ;NUM1转换为浮点型储存格式
 766 NUM1_CONVERSION_FLOAT:
 767         MOV NUM1_MANTISSA3,NUM1_LOW
 768         MOV NUM1_MANTISSA2,NUM1_HIGH
 769         MOV    NUM1_EXPONENT,#151;127+24=151
 770 
 771 DECI1_COMP_SOLVE:
 772         MOV A,NUM1_DECI_COMP
 773         MOV B,#10
 774         MUL AB
 775         MOV NUM1_DECI_COMP,A
 776         DJNZ LEN1_DECIMAL,DECI1_COMP_SOLVE
 777 
 778 ;十进制小数位转二进制
 779 DECI1_COMP:
 780         CLR C
 781         MOV A,NUM1_DECIMAL_L
 782         RLC    A
 783         MOV NUM1_DECIMAL_L,A
 784         CJNE A,NUM1_DECI_COMP,DECI1_COMP_NEQ
 785 DECI1_COMP_EQ:
 786         MOV NUM1_DECIMAL_L,#000H
 787         SETB C
 788         JMP NUM1_MANTISSA_RLC
 789 DECI1_COMP_NEQ:
 790         JC DECI1_COMP_LESS
 791         CLR C
 792         MOV A,NUM1_DECIMAL_L
 793         SUBB A,NUM1_DECI_COMP
 794         MOV NUM1_DECIMAL_L,A
 795         SETB C
 796         JMP NUM1_MANTISSA_RLC
 797 DECI1_COMP_LESS:
 798         CLR C
 799 ;尾数位集体左移
 800 NUM1_MANTISSA_RLC:
 801         MOV A,NUM1_MANTISSA3
 802         RLC    A
 803         MOV NUM1_MANTISSA3,A
 804         MOV A,NUM1_MANTISSA2
 805         RLC    A
 806         MOV NUM1_MANTISSA2,A
 807         MOV A,NUM1_MANTISSA1
 808         RLC    A
 809         MOV NUM1_MANTISSA1,A
 810         ;记录小数指数
 811         DEC    NUM1_EXPONENT
 812         JNC DECI1_COMP
 813 ;浮点数集体右移
 814         CLR C
 815         MOV A,NUM1_EXPONENT
 816         RRC    A
 817         MOV NUM1_EXPONENT,A
 818         MOV A,NUM1_MANTISSA1
 819         RRC    A
 820         MOV NUM1_MANTISSA1,A
 821         MOV A,NUM1_MANTISSA2
 822         RRC    A
 823         MOV NUM1_MANTISSA2,A
 824         MOV A,NUM1_MANTISSA3
 825         RRC    A
 826         MOV NUM1_MANTISSA3,A
 827         
 828 ;NUM2转换为浮点型储存格式
 829 NUM2_CONVERSION_FLOAT:
 830         MOV NUM2_MANTISSA3,NUM2_LOW
 831         MOV NUM2_MANTISSA2,NUM2_HIGH
 832         MOV    NUM2_EXPONENT,#151;127+24=151
 833 
 834 DECI2_COMP_SOLVE:
 835         MOV A,NUM2_DECI_COMP
 836         MOV B,#10
 837         MUL AB
 838         MOV NUM2_DECI_COMP,A
 839         DJNZ LEN2_DECIMAL,DECI2_COMP_SOLVE
 840 
 841 ;十进制小数位转二进制
 842 DECI2_COMP:
 843         CLR C
 844         MOV A,NUM2_DECIMAL_L
 845         RLC    A
 846         MOV NUM2_DECIMAL_L,A
 847         CJNE A,NUM2_DECI_COMP,DECI2_COMP_NEQ
 848 DECI2_COMP_EQ:
 849         MOV NUM2_DECIMAL_L,#000H
 850         SETB C
 851         JMP NUM2_MANTISSA_RLC
 852 DECI2_COMP_NEQ:
 853         JC DECI2_COMP_LESS
 854         CLR C
 855         MOV A,NUM2_DECIMAL_L
 856         SUBB A,NUM2_DECI_COMP
 857         MOV NUM2_DECIMAL_L,A
 858         SETB C
 859         JMP NUM2_MANTISSA_RLC
 860 DECI2_COMP_LESS:
 861         CLR C
 862 ;尾数位集体左移
 863 NUM2_MANTISSA_RLC:
 864         MOV A,NUM2_MANTISSA3
 865         RLC    A
 866         MOV NUM2_MANTISSA3,A
 867         MOV A,NUM2_MANTISSA2
 868         RLC    A
 869         MOV NUM2_MANTISSA2,A
 870         MOV A,NUM2_MANTISSA1
 871         RLC    A
 872         MOV NUM2_MANTISSA1,A
 873         ;记录小数指数
 874         DEC    NUM2_EXPONENT
 875         JNC DECI2_COMP
 876 ;浮点数集体右移
 877         CLR C
 878         MOV A,NUM2_EXPONENT
 879         RRC    A
 880         MOV NUM2_EXPONENT,A
 881         MOV A,NUM2_MANTISSA1
 882         RRC    A
 883         MOV NUM2_MANTISSA1,A
 884         MOV A,NUM2_MANTISSA2
 885         RRC    A
 886         MOV NUM2_MANTISSA2,A
 887         MOV A,NUM2_MANTISSA3
 888         RRC    A
 889         MOV NUM2_MANTISSA3,A
 890 
 891 ;至此完成所有转换,可以开始计算
 892 PLUS_FLOAT_START:
 893         ;恢复NUM1指数位
 894         MOV A,NUM1_MANTISSA1
 895         RLC A
 896         MOV A,NUM1_EXPONENT
 897         RLC A
 898         MOV NUM1_EXPONENT,A
 899         ;恢复NUM1有效数字位
 900         MOV A,NUM1_MANTISSA1
 901         ORL A,#080H
 902         MOV NUM1_MANTISSA1,A
 903         ;恢复NUM2指数位
 904         MOV A,NUM2_MANTISSA1
 905         RLC A
 906         MOV A,NUM2_EXPONENT
 907         RLC A
 908         MOV NUM2_EXPONENT,A
 909         ;恢复NUM2有效数字位
 910         MOV A,NUM2_MANTISSA1
 911         ORL A,#080H
 912         MOV NUM2_MANTISSA1,A
 913 ;以大的为标准移动小数点
 914 FLOAT_COMPARE:
 915         MOV A,NUM1_EXPONENT
 916         CJNE A,NUM2_EXPONENT,FLOAT_NEQ
 917 FLOAT_EQ:
 918         JMP FLOAT_ADD
 919 FLOAT_NEQ:
 920         JC FLOAT_RRNUM1
 921 ;NUM1较大 NUM2右移
 922 FLOAT_RRNUM2:
 923         INC NUM2_EXPONENT
 924         CLR C
 925         MOV A,NUM2_MANTISSA1
 926         RRC A
 927         MOV NUM2_MANTISSA1,A
 928         MOV A,NUM2_MANTISSA2
 929         RRC A
 930         MOV NUM2_MANTISSA2,A
 931         MOV A,NUM2_MANTISSA3
 932         RRC A
 933         MOV NUM2_MANTISSA3,A
 934         MOV A,NUM1_EXPONENT
 935         CJNE A,NUM2_EXPONENT,FLOAT_RRNUM2;
 936         LJMP FLOAT_ADD;
 937 ;NUM1较小 NUM1右移
 938 FLOAT_RRNUM1:
 939         INC NUM1_EXPONENT
 940         CLR C
 941         MOV A,NUM1_MANTISSA1
 942         RRC A
 943         MOV NUM1_MANTISSA1,A
 944         MOV A,NUM1_MANTISSA2
 945         RRC A
 946         MOV NUM1_MANTISSA2,A
 947         MOV A,NUM1_MANTISSA3
 948         RRC A
 949         MOV NUM1_MANTISSA3,A
 950         MOV A,NUM1_EXPONENT
 951         CJNE A,NUM2_EXPONENT,FLOAT_RRNUM1
 952         LJMP FLOAT_ADD;
 953 ;两数相加
 954 FLOAT_ADD:
 955         MOV A,NUM1_MANTISSA3
 956         ADD A,NUM2_MANTISSA3
 957         MOV SUM_MANTISSA3,A
 958         
 959         MOV A,NUM1_MANTISSA2
 960         ADDC A,NUM2_MANTISSA2
 961         MOV SUM_MANTISSA2,A
 962         
 963         MOV A,NUM1_MANTISSA1
 964         ADDC A,NUM2_MANTISSA1
 965         MOV SUM_MANTISSA1,A
 966         
 967         MOV SUM_EXPONENT,NUM2_EXPONENT
 968         JNC FLOAT_RECOVER
 969 ;有进位现象 SUM右移
 970 FLOAT_RRSUM:
 971         INC SUM_EXPONENT
 972         SETB C
 973         MOV A,SUM_MANTISSA1
 974         RRC A
 975         MOV SUM_MANTISSA1,A
 976         MOV A,SUM_MANTISSA2
 977         RRC A
 978         MOV SUM_MANTISSA2,A
 979         MOV A,SUM_MANTISSA3
 980         RRC A
 981         MOV SUM_MANTISSA3,A
 982 ;恢复原有格式
 983 FLOAT_RECOVER:
 984         ;;左移丢掉第一位
 985         ;MOV A,SUM_MANTISSA1
 986         ;RL A
 987         ;MOV SUM_MANTISSA1,A
 988         ;;指数位和第一个尾数位同时右移
 989         ;CLR C
 990         ;MOV A,SUM_EXPONENT
 991         ;RRC A
 992         ;MOV SUM_EXPONENT,A
 993         ;MOV A,SUM_MANTISSA1
 994         ;RRC A
 995         ;MOV SUM_MANTISSA1, A
 996 
 997 ;调试用
 998         ;MOV SUM_EXPONENT,#82H;结果SUM高十六位
 999         ;MOV SUM_MANTISSA1,#0AAH;
1000         ;MOV SUM_MANTISSA2,#000H;结果SUM低十六位
1001         ;MOV SUM_MANTISSA3,#000H;
1002         
1003         ;;恢复SUM指数位
1004         ;MOV A,SUM_MANTISSA1
1005         ;RLC A
1006         ;MOV A,SUM_EXPONENT
1007         ;RLC A
1008         ;MOV SUM_EXPONENT,A
1009         ;;恢复SUM有效数字位
1010         ;MOV A,SUM_MANTISSA1
1011         ;ORL A,#080H
1012         ;MOV SUM_MANTISSA1,A
1013 
1014 ;完成运算
1015         MOV NUM1_LOW,#000H;
1016         MOV NUM1_HIGH,#000H;
1017 SEND_NUM1:
1018         MOV A,SUM_EXPONENT
1019         CJNE A,#127,SUM_NEQ
1020 ;MANTISSA左移送入NUM1 完成运算
1021 SUM_EQ:
1022         CLR C
1023         MOV A,SUM_MANTISSA3
1024         RLC    A
1025         MOV SUM_MANTISSA3,A
1026         MOV A,SUM_MANTISSA2
1027         RLC    A
1028         MOV SUM_MANTISSA2,A
1029         MOV A,SUM_MANTISSA1
1030         RLC    A
1031         MOV SUM_MANTISSA1,A
1032         MOV A,NUM1_LOW
1033         RLC    A
1034         MOV NUM1_LOW,A
1035         MOV A,NUM1_HIGH
1036         RLC    A
1037         MOV NUM1_HIGH,A
1038         JMP PLUS_END
1039 ;SUM_EXPONENT较大 MANTISSA左移送入NUM1 EXPONENT自减
1040 SUM_NEQ:
1041         JC SUM_LESS
1042         CLR C
1043         MOV A,SUM_MANTISSA3
1044         RLC    A
1045         MOV SUM_MANTISSA3,A
1046         MOV A,SUM_MANTISSA2
1047         RLC    A
1048         MOV SUM_MANTISSA2,A
1049         MOV A,SUM_MANTISSA1
1050         RLC    A
1051         MOV SUM_MANTISSA1,A
1052         MOV A,NUM1_LOW
1053         RLC    A
1054         MOV NUM1_LOW,A
1055         MOV A,NUM1_HIGH
1056         RLC    A
1057         MOV NUM1_HIGH,A
1058         DEC SUM_EXPONENT
1059         JMP SEND_NUM1
1060 ;SUM_EXPONENT较小 MANTISSA右移 EXPONENT自增
1061 SUM_LESS:
1062         CLR C
1063         MOV A,SUM_MANTISSA1
1064         RLC    A
1065         MOV SUM_MANTISSA1,A
1066         MOV A,SUM_MANTISSA2
1067         RLC    A
1068         MOV SUM_MANTISSA2,A
1069         MOV A,SUM_MANTISSA3
1070         RLC    A
1071         MOV SUM_MANTISSA3,A
1072         INC SUM_EXPONENT
1073         JMP SEND_NUM1
1074 PLUS_END:
1075         RET
1076 
1077 ;--------双字节减法运算--------;
1078 SUBTRACT:
1079         CLR C
1080         MOV A,NUM1_LOW
1081         SUBB A,NUM2_LOW
1082         MOV NUM1_LOW,A
1083         MOV A,NUM1_HIGH
1084         SUBB A,NUM2_HIGH
1085         MOV NUM1_HIGH,A
1086         RET
1087 
1088 ;--------双字节移位乘法运算--------;
1089 MULTIPLY:
1090         MOV ADDEND_LOW,#0
1091         MOV ADDEND_HIGH,#0
1092         MOV PRODUCT_LOW,#0
1093         MOV PRODUCT_HIGH,#0
1094         MOV POSITION_BIN,#0
1095 MULTIPLY_LOOP:
1096         ;右移MULTI2
1097         CLR C
1098         MOV A,MULTI2_HIGH
1099         RRC A
1100         MOV MULTI2_HIGH,A
1101         MOV A,MULTI2_LOW
1102         RRC A
1103         MOV MULTI2_LOW,A
1104         ;记录MULTI2的第几位
1105         INC POSITION_BIN
1106         ;判断是否需要移位相加
1107         JNC    MULTIPLY_JUDGE
1108         
1109         MOV ADDEND_LOW,MULTI1_LOW
1110         MOV ADDEND_HIGH,MULTI1_HIGH
1111         MOV R2,POSITION_BIN
1112         ;R2为1直接相加,不用移位
1113         DJNZ R2,MULTIPLY_LEFT
1114         JMP MULTIPLY_ADDITION
1115 
1116 MULTIPLY_LEFT:    
1117         ;左移ADDEND
1118         CLR C
1119         MOV A,ADDEND_LOW
1120         RLC A
1121         MOV ADDEND_LOW,A
1122         
1123         MOV A,ADDEND_HIGH
1124         RLC A
1125         MOV ADDEND_HIGH,A
1126 
1127         DJNZ R2,MULTIPLY_LEFT
1128 
1129 MULTIPLY_ADDITION:
1130         MOV A,PRODUCT_LOW
1131         ADD    A,ADDEND_LOW
1132         MOV PRODUCT_LOW,A
1133         
1134         MOV A,PRODUCT_HIGH
1135         ADDC A,ADDEND_HIGH
1136         MOV PRODUCT_HIGH,A
1137 ;判断是否移满16位
1138 MULTIPLY_JUDGE:        
1139         MOV A,POSITION_BIN
1140         CJNE A,#010H,MULTIPLY_LOOP
1141 
1142         RET
1143 
1144 ;--------双字节移位除法运算--------;
1145 DIVIDE:
1146         MOV LEN_NUM,#16;双字节长度16
1147         MOV DIVIDEND_LOW,#0
1148         MOV DIVIDEND_HIGH,#0
1149         MOV QUOTIENT_LOW,#0
1150         MOV QUOTIENT_HIGH,#0
1151 DIVIDE_LOOP:
1152         ;左移NUM1
1153         CLR C
1154         MOV A,NUM1_LOW
1155         RLC A
1156         MOV NUM1_LOW,A
1157         
1158         MOV A,NUM1_HIGH
1159         RLC A
1160         MOV NUM1_HIGH,A
1161         ;左移DIVIDEND
1162         MOV A,DIVIDEND_LOW
1163         RLC A
1164         MOV DIVIDEND_LOW,A
1165         
1166         MOV A,DIVIDEND_HIGH
1167         RLC A
1168         MOV DIVIDEND_HIGH,A
1169         ;比较高八位
1170         MOV A,DIVIDEND_HIGH
1171         CJNE A,DIVISOR_HIGH,DIVIDE_NEQ2
1172 ;相等则判断低八位
1173 DIVIDE_EQ1:
1174         JMP DIVIDE_JUDGE
1175 DIVIDE_NEQ1:
1176         ;小于则直接跳过
1177         JC DIVIDE_LOW
1178         ;大于则直接相减
1179         CLR C
1180         MOV A,DIVIDEND_LOW
1181         SUBB A,DIVISOR_LOW
1182         MOV DIVIDEND_LOW,A
1183         
1184         MOV A,DIVIDEND_HIGH
1185         SUBB A,DIVISOR_HIGH
1186         MOV DIVIDEND_HIGH,A
1187         ;左移QUOTIENT
1188         SETB C
1189         MOV A,QUOTIENT_LOW
1190         RLC A
1191         MOV QUOTIENT_LOW,A
1192         
1193         MOV A,QUOTIENT_HIGH
1194         RLC A
1195         MOV QUOTIENT_HIGH,A
1196         DJNZ LEN_NUM,DIVIDE_LOOP
1197         JMP    DIVIDE_END
1198 ;低八位判断
1199 DIVIDE_JUDGE:
1200         MOV A,DIVIDEND_LOW
1201         CJNE A,DIVISOR_LOW,DIVIDE_NEQ2
1202 DIVIDE_EQ2:
1203         MOV DIVIDEND_LOW,#0
1204         MOV DIVIDEND_HIGH,#0
1205         ;左移QUOTIENT
1206         SETB C
1207         MOV A,QUOTIENT_LOW
1208         RLC A
1209         MOV QUOTIENT_LOW,A
1210         
1211         MOV A,QUOTIENT_HIGH
1212         RLC A
1213         MOV QUOTIENT_HIGH,A
1214         DJNZ LEN_NUM,DIVIDE_LOOP
1215         JMP    DIVIDE_END
1216 DIVIDE_NEQ2:
1217         ;小于则跳过
1218         JC DIVIDE_LOW
1219         ;大于则相减
1220         MOV DIVIDEND_HIGH,#0
1221         CLR C
1222         SUBB A,DIVISOR_LOW
1223         MOV DIVIDEND_LOW,A
1224         ;左移QUOTIENT
1225         SETB C
1226         MOV A,QUOTIENT_LOW
1227         RLC A
1228         MOV QUOTIENT_LOW,A
1229         
1230         MOV A,QUOTIENT_HIGH
1231         RLC A
1232         MOV QUOTIENT_HIGH,A
1233         DJNZ LEN_NUM,DIVIDE_LOOP
1234         JMP    DIVIDE_END
1235 ;小于则只需左移QUOTIENT
1236 DIVIDE_LOW:
1237         ;左移QUOTIENT
1238         CLR C
1239         MOV A,QUOTIENT_LOW
1240         RLC A
1241         MOV QUOTIENT_LOW,A
1242         
1243         MOV A,QUOTIENT_HIGH
1244         RLC A
1245         MOV QUOTIENT_HIGH,A
1246         DJNZ LEN_NUM,DIVIDE_LOOP
1247         JMP    DIVIDE_END
1248 DIVIDE_END:
1249         MOV NUM1_LOW,QUOTIENT_LOW
1250         MOV NUM1_HIGH,QUOTIENT_HIGH
1251         MOV REMAINDER_LOW,DIVIDEND_LOW
1252         MOV REMAINDER_HIGH,DIVIDEND_HIGH
1253 
1254         RET
1255 
1256 ;--------错误处理--------;
1257 FAULT:
1258         RET
1259 
1260 ;--------读取矩阵键盘键值--------;
1261 KEY_READ:    
1262         MOV KEY,#0F0H;读高四位
1263         MOV A,KEY
1264         ORL A,#00FH;低四位置1
1265         MOV KEY_Y,A;高四位列信息
1266         MOV KEY,#00FH;读低四位
1267         MOV A,KEY
1268         ORL A,#0F0H;高四位置1
1269         MOV KEY_X,A;低四位行信息
1270         ANL A,KEY_Y
1271         MOV KEY_XY,A
1272 ;松手执行
1273 JUDGE_RELAX:
1274         MOV KEY,#0F0H;读高四位
1275         MOV A,KEY
1276         CJNE A,#0F0H,JUDGE_RELAX
1277 COMFIRM_RELAX:
1278         ACALL DELAY;软件去抖
1279         MOV KEY,#00FH;读低四位
1280         MOV A,KEY
1281         CJNE A,#00FH,JUDGE_RELAX
1282 ;确定KEYNUM
1283 CONFIRM_KEYNUM:
1284         MOV R0,KEYADD
1285         MOV KEYNUM_LAST,@R0
1286 INIT_KEY:
1287         MOV @R0,#0FFH
1288         MOV DPTR,#KEY_TABLE
1289         MOV R2,#21;自增21次,KEYNUM最大20
1290 JUDGE_EXCESS:
1291         INC @R0
1292         DJNZ R2,JUDGE_EQUAL
1293         JMP KEY_END
1294 JUDGE_EQUAL:    
1295         MOV A,@R0
1296         MOVC A,@A+DPTR
1297         CJNE A,KEY_XY,JUDGE_EXCESS
1298 KEY_END:    
1299         RET
1300 
1301 KEY_TABLE:    
1302         DB 0D7H;1101 0111B;K14(0)
1303         DB 0EBH;1110 1011B;K9 (1)
1304         DB 0DBH;1101 1011B;K10(2)
1305         DB 0BBH;1011 1011B;K11(3)
1306         DB 0EDH;1110 1101B;K5 (4)
1307         DB 0DDH;1101 1101B;K6 (5)
1308         DB 0BDH;1011 1101B;K7 (6)
1309         DB 0EEH;1110 1110B;K1 (7)
1310         DB 0DEH;1101 1110B;K2 (8)
1311         DB 0BEH;1011 1110B;K3 (9)
1312         DB 0E7H;1110 0111B;K13(<)10
1313         DB 0B7H;1011 0111B;K15(>)11
1314         DB 07EH;0111 1110B;K4 (c)12
1315         DB 07DH;0111 1101B;K8 (.)13
1316         DB 077H;0111 0111B;K16(=)14
1317         DB 07BH;0111 1011B;K12(O)+ - * /
1318                 
1319 ;--------数码管显示--------;
1320 DISPLAY:    
1321         MOV R0,#NUM1ADD
1322         MOV R2,LED_CS
1323         MOV R3,#07FH
1324 DIS_LOOP:    
1325         MOV A,R2
1326         RLC A
1327         MOV R2,A
1328         ;段选查表
1329         MOV DPTR,#DIS_TABLE
1330         MOV A,@R0
1331         MOVC A,@A+DPTR
1332         MOV P0,A
1333         INC R0
1334         JC SKIP
1335         ;片选延时
1336         MOV P2,R3
1337         DJNZ LED_NUM,$
1338         MOV LED_NUM,#LUMINANCE
1339         MOV P2,#0FFH
1340 SKIP:         
1341         SETB C
1342         MOV A,R3
1343         RRC A
1344         MOV R3,A
1345         JC DIS_LOOP
1346         RET
1347 
1348 DIS_TABLE:    
1349         DB 03FH,006H,05BH,04FH;0 1 2 3
1350         DB 066H,06DH,07DH,007H;4 5 6 7
1351         DB 07FH,06FH,008H,008H;8 9 _ _
1352         DB 000H,000H,000H,000H;       
1353         DB 03EH,040H,037H,049H;+ - * /
1354         DB 071H,071H,071H,071H;F F F F
1355         DB 071H,071H,071H,071H;F F F F
1356         DB 071H,071H,071H,071H;F F F F
1357         DB 0BFH,086H,0DBH,0CFH;0. 1. 2. 3.
1358         DB 0E6H,0EDH,0FDH,087H;4. 5. 6. 7.
1359         DB 0FFH,0EFH,000H,000H;8. 9.
1360 
1361 ;--------延时函数--------;
1362 DELAY:        
1363         MOV DELAY1,#100
1364         MOV DELAY2,#100
1365         MOV DELAY3,#2;延时约2*10=20MS
1366 DELAY_LOOP:    
1367         DJNZ DELAY1,DELAY_LOOP
1368         MOV DELAY1,#100
1369         DJNZ DELAY2,DELAY_LOOP
1370         MOV DELAY2,#100
1371         DJNZ DELAY3,DELAY_LOOP
1372         RET
1373 
1374 INT_EX0:
1375 
1376 ;--------数码管动态显示--------;
1377 INT_TIMER0:    
1378         PUSH 00H;R0压栈
1379         PUSH 01H;R1压栈
1380         MOV A,R1;A借用R1的地址
1381         PUSH 01H;A压栈
1382         PUSH 02H;R2压栈
1383         PUSH 03H;R3压栈
1384         MOV TH0,#0ECH;
1385         MOV TL0,#078H;初值为60536
1386         ACALL DISPLAY
1387         POP 03H;R3出栈
1388         POP 02H;R2出栈
1389         POP 01H;A出栈
1390         MOV A,R1;A借用R1的地址
1391         POP 01H;R1出栈
1392         POP 00H;R0出栈
1393         RETI
1394             
1395 INT_EX1:
1396 
1397 ;--------最后一位闪烁--------;
1398 INT_TIMER1:
1399         PUSH 01H;R1压栈
1400         MOV A,R1;A借用R1的地址
1401         PUSH 01H;A压栈
1402         MOV TH1,#03CH;
1403         MOV TL1,#0B0H;初值为15536
1404         DJNZ T1_NUM,TIMER1_END
1405         MOV T1_NUM,#10;定时50*10=500MS
1406         MOV A,TWINKLE
1407         CPL ON_OFF
1408         JB ON_OFF,LED_ON
1409 LED_OFF:    
1410         ORL LED_CS,A;灭灯
1411         JMP TIMER1_END
1412 LED_ON:        
1413         CPL A
1414         ANL LED_CS,A;亮灯
1415 TIMER1_END:    
1416         POP 01H;A出栈
1417         MOV A,R1;A借用R1的地址
1418         POP 01H;R1出栈
1419         RETI
1420 
1421 INT_UART:
1422 
1423 END

 

 

 

posted @ 2022-10-15 20:36  Kelvin-Wu  阅读(463)  评论(0编辑  收藏  举报