找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3804|回复: 0
收起左侧

制作的单片机+8255电子计算器汇编语言程序,带Proteus仿真

[复制链接]
ID:656224 发表于 2019-12-11 19:55 | 显示全部楼层 |阅读模式
可实现加减乘除,除法可显示小数点后一位,实现连加减运算
51hei.png

单片机源程序如下:

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.png
全部资料51hei下载地址:
计算器.rar (24.5 KB, 下载次数: 74)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表