【微机原理大作业】从0开始设计RTC电子钟系统(三)(含完整源码和仿真图及下载地址)

【微机原理作业】从0开始设计RTC系统(一)
【微机原理作业】从0开始设计RTC系统(二)(初步构图和代码子模块)
上两篇博客实现了秒表功能,但我们希望钟表还有调整时钟的功能,所以需要外加一个按键调整时钟电路⭐️。

效果演示🔥

演示视频

思路

思路框图

仿真硬件

8255A :A、B口输出,C口上部输出,下部输入
8255A重置清零按钮按下后,时钟从0开始计时
秒调整按钮按下后,秒数加1,其余类似
其余硬件不变

汇编程序

主程序

LP:
    ; 主任务
    CALL KEY
    CALL DISP    ; 显示子程序调用
    JMP LP   ; 循环

按键

KEY   PROC
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JZ NEXTHOU 
    TEST AL, 4H     
    JZ NEXTMIN
    TEST AL, 2H      
    JZ NEXTSEC
    TEST AL, 1H
    JZ RESET
    CALL DISP       ; 消抖
    CALL DISP 
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JZ NEXTHOU 
    TEST AL, 4H
    JZ NEXTMIN
    TEST AL, 2H
    JZ NEXTSEC
    TEST AL, 1H
    JZ RESET

重置清零

RESET: 
    ; 清零
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 1H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 1H
    JNZ EXITKEY    
    MOV HOU, 0
    MOV MIN, 0
    MOV SEC, 0
    CALL DELAY

调整秒

NEXTSEC: 
    ; 秒调整
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 2H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 2H
    JNZ EXITKEY
    MOV AL, SEC
    ADD AL, 1
    DAA         
    CALL DELAY        
    MOV SEC, AL
    CMP SEC, 60H
    JB NEXTSEC
    MOV SEC, 0  

调整分

NEXTMIN: 
    ; 分调整
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 4H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 4H
    JNZ EXITKEY
    MOV AL, MIN
    ADD AL, 1
    DAA      
    CALL DELAY     
    MOV MIN, AL
    CMP MIN, 60H
    JB NEXTMIN
    MOV MIN, 0

调整时

NEXTHOU: 
    ; 时调整
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JNZ EXITKEY
    MOV AL, HOU
    ADD AL, 1     
    DAA 
    CALL DELAY       
    MOV HOU, AL
    CMP HOU, 24H
    JB NEXTHOU
    MOV HOU, 0

问题

  1. 仿真报错:invalid internal memory size == NULL(internal memory mode)
    解决:将8086中的参数设置第2项 ,设置 intener memory 为10000

  2. 时钟最小单位不是1秒
    解决:修改分频数和延时

  3. 调时过快
    解决:修改延时

  4. 字符9和8显示不全
    上网查:
    (1)延时不够,出现鬼影
    (2)显示字符之前没有清零
    这些方法我都试过了,但没有解决问题。


问题解决

时隔108天,终于在2020.9.29下午的微机课上解决了这个问题!🙋
老师说,可能是因为内存重叠导致部分字符显示不全。

在原理图中点击 8086 CPU,修改 Advanced Properties 中的参数:

Program Loading Segment:0x0800 → 0x0200

BIN Entry Point:0x00000 → 0x02000

终于能正常显示字符啦!🙏🙏🙏🙏🙏

成功!

完整proteus原理图🔥

原理图

完整代码🔥

以下就是完整代码了:

;************************************************************************
; file:    rtc.asm
; author: Xiaoxiao
; date:   20200929
; blog:    https://blog.csdn.net/weixin_43470383/category_10041680.html
;************************************************************************

DATA SEGMENT
    ; 3-8译码器输出对应端口
    IO2 EQU 20H   ; 8253A
    IO4 EQU 40H   ; 8255A 
    
    TIME0      EQU IO2      ; T0地址
    TIME1      EQU IO2 + 2  ; T1地址
    TIME_CTR   EQU IO2 + 6  ; 8253A控制口地址
    
    PORTA EQU IO4          ; 8255 A口地址
    PORTB EQU IO4 + 2      ; 8255 B口地址
    PORTC EQU IO4 + 4      ; 8255 C口地址 
    PORT_CTR  EQU  IO4 + 6 ; 8255 控制口地址
    
    CNTVAL EQU 1000H ; 计数初值
    
    LED DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
    ;0--9 对应段选码,共阴极 
    
    HOU DB 00H ; 时 
    MIN DB 00H ; 分 
    SEC DB 00H ; 秒
DATA ENDS

STACK SEGMENT
    DW   200  DUP(0) ; 这里不用给太多,一两百就够
STACK ENDS

CODE SEGMENT  
    ASSUME CS:CODE,DS:DATA,SS:STACK
    
START:
    ; 数据段设置
    MOV AX, DATA
    MOV DS, AX
    MOV ES, AX
    
    ; NMI中断向量初始化
    PUSH ES
    XOR AX, AX 
    MOV ES, AX
    MOV AL, 02H ; NMI中断类型号为02H
    XOR AH, AH
    SHL AX, 1   
    SHL AX, 1   
    MOV SI, AX
    MOV AX, OFFSET NMI_SERVICE 
    MOV ES: [SI], AX
    INC SI
    INC SI
    MOV BX, CS
    MOV ES: [SI], BX
    POP ES   
    
    ; 初始化8253
    MOV AL, 00110101B ; T0 读写16位 方式2 BCD计数
    MOV DX, TIME_CTR   
    OUT DX, AL
    MOV DX, TIME0        
    MOV AX, CNTVAL    ; 1000分频
    OUT DX, AL
    
    MOV AL, AH        ; 高字节
    OUT DX, AL
    
    MOV AL, 01110111B ; T1 读写16位 方式3 BCD计数
    MOV DX, TIME_CTR   
    OUT DX, AL
    MOV DX, TIME1   
    MOV AX, CNTVAL    ; 1000分频
    OUT DX, AL
    
    MOV AL, AH        ; 高字节
    OUT DX, AL   
    
    ; 初始化8255
    MOV AL, 81H ; A、B输出,C上部输出,下部输入
    OUT PORT_CTR, AL
    
LP:
    ; 主任务
    CALL KEY
    CALL DISP    ; 显示子程序调用
    JMP LP       ; 循环

NMI_SERVICE: 
    ; 中断服务
    PUSH AX
    MOV AL, SEC
    ADD AL, 1
    DAA          ; 校正BCD数加法    
    
    MOV SEC, AL
    CMP SEC, 60H 
    JB  EXIT      
    MOV SEC, 0
    MOV AL,  MIN
    ADD AL,  1
    DAA
    
    MOV MIN, AL
    CMP MIN, 60H
    JB  EXIT
    MOV MIN, 0
    MOV AL,  HOU
    ADD AL,  1
    DAA
    
    MOV HOU, AL
    CMP HOU, 24H
    JB  EXIT
    MOV HOU, 0
    
EXIT: 
    POP AX
    IRET       ; 中断返回
          
DISP PROC 
     ; 数码管显示子程序  
     MOV AL, 0FFH   ; 不显示
     MOV DX, PORTB
     OUT DX, AL     ; 位选信号接到8255A的PB口
     
     ; 秒个位
     MOV AL, 0FEH   
     MOV DX, PORTB          
     OUT DX, AL     ; 位选
     
     MOV BL, SEC    ; 存放8位秒数
     AND BX, 000FH  
     MOV SI, BX 
     MOV AL, LED[SI]  
     MOV DX, PORTA  
     OUT DX, AL       ; 段选
     CALL DELAY            
   
     MOV AL, 0FFH   ; 为防止重叠,每次显示之前要清零
     MOV DX, PORTB
     OUT DX, AL       
     
     MOV BL, SEC
     AND BX, 00F0H
     MOV CL, 4
     SHR BX, CL      
     MOV SI, BX
 
     MOV AL, 0FDH   ; 秒十位
     MOV DX, PORTB          
     OUT DX, AL
             
     MOV AL, LED[SI]  ; 段码
     MOV DX, PORTA
     OUT DX, AL
     CALL DELAY          
     
     MOV AL, 0FFH   ; 不显示
     MOV DX, PORTB
     OUT DX, AL  
                
     MOV AL, 40H    ; "-"段码  
     MOV DX, PORTA
     OUT DX, AL
     
     MOV AL, 0FBH   ; "-"位
     MOV DX, PORTB
     OUT DX, AL
     CALL DELAY   
     
     MOV AL, 0FFH   ; 不显示
     MOV DX, PORTB
     OUT DX, AL    
     
     MOV BL, MIN
     AND BX, 000FH
     MOV SI, BX
     MOV AL, LED[SI]  ; 段码
     MOV DX, PORTA
     OUT DX, AL
     
     MOV AL, 0F7H     ; 分个位
     MOV DX, PORTB
     OUT DX, AL
     CALL DELAY  
                      
     MOV AL, 0FFH     ; 不显示
     MOV DX, PORTB
     OUT DX, AL  
     
     MOV BL, MIN
     AND BX, 00F0H
     MOV CL, 4
     SHR BX, CL       
     MOV SI, BX
     MOV AL, LED[SI]  ; 段码 
     MOV DX, PORTA
     OUT DX, AL
     
     MOV AL, 0EFH   ; 分十位
     MOV DX, PORTB          
     OUT DX, AL
     CALL DELAY  
     
     MOV AL, 0FFH   ; 不显示
     MOV DX, PORTB
     OUT DX, AL   
     
     MOV AL, 40H    ; 段码“-”  
     AND DX, PORTA
     OUT DX, AL
     
     MOV AL, 0DFH   ; "-"位
     MOV DX, PORTB
     OUT DX, AL
     CALL DELAY 
     
     MOV AL, 0FFH   ; 不显示
     MOV DX, PORTB
     OUT DX, AL    

     MOV BL, HOU
     AND BX, 000FH
     MOV SI, BX
     MOV AL, LED[SI]  ; 段码
     MOV DX, PORTA
     OUT DX, AL
     
     MOV AL, 0BFH     ; 时个位
     MOV DX, PORTB
     OUT DX, AL
     CALL DELAY               
     
     MOV AL, 0FFH     ; 不显示
     MOV DX, PORTB
     OUT DX, AL  
     
     MOV BL, HOU
     AND BX, 00F0H
     MOV CL, 4
     SHR BX, CL       
     MOV SI, BX
     MOV AL, LED[SI]  ; 段码 
     MOV DX, PORTA
     OUT DX, AL  
     
     MOV AL, 07FH     ; 时十位
     MOV DX, PORTB
     OUT DX, AL
     CALL DELAY
     
     RET              ; 子程序返回
DISP ENDP
          
KEY   PROC
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JZ NEXTHOU 
    TEST AL, 4H     
    JZ NEXTMIN
    TEST AL, 2H      
    JZ NEXTSEC
    TEST AL, 1H
    JZ RESET
    CALL DISP       ; 消抖
    CALL DISP 
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JZ NEXTHOU 
    TEST AL, 4H
    JZ NEXTMIN
    TEST AL, 2H
    JZ NEXTSEC
    TEST AL, 1H
    JZ RESET

NEXTHOU: 
    ; 时调整
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 8H
    JNZ EXITKEY
    MOV AL, HOU
    ADD AL, 1     
    DAA 
    CALL DELAY   
    
    MOV HOU, AL
    CMP HOU, 24H
    JB NEXTHOU
    MOV HOU, 0

NEXTMIN: 
    ; 分调整
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 4H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 4H
    JNZ EXITKEY
    MOV AL, MIN
    ADD AL, 1
    DAA      
    CALL DELAY 
    
    MOV MIN, AL
    CMP MIN, 60H
    JB NEXTMIN
    MOV MIN, 0    

NEXTSEC: 
    ; 秒调整
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 2H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 2H
    JNZ EXITKEY
    MOV AL, SEC
    ADD AL, 1
    DAA         
    CALL DELAY        
    MOV SEC, AL
    CMP SEC, 60H
    JB NEXTSEC
    MOV SEC, 0  

RESET: 
    ; 清零
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 1H
    JNZ EXITKEY  
    CALL DISP
    CALL DISP
    CALL DISP
    MOV DX, PORTC
    IN AL, DX
    TEST AL, 1H
    JNZ EXITKEY    
    MOV HOU, 0
    MOV MIN, 0
    MOV SEC, 0
    CALL DELAY
    
EXITKEY:
    RET
    
KEY ENDP

DELAY PROC
      ; 延时子程序 
      PUSH BX
      PUSH CX
      MOV BX, 1
LP1:  MOV CX, 1000
LP2:  LOOP LP2
      DEC BX
      JNZ LP1
      POP CX
      POP BX   
      RET    
DELAY ENDP
               
CODE ENDS

    END START 

效果演示🔥

演示视频

原理图和程序文件下载🔥

下载地址1
下载地址2
(资源能正常使用的!正常运行不会有报错!但如果没有proteus或者不会用proteus进行仿真的话是没法用的哦!!!遇到问题建议多检查原理图)
使用方法可以参考:如何用Proteus仿真8086
源码在本博客已经给出,如果仍然无法实现,可以检查一下原理图,看看有没有问题

等等,还没完…
老师说系统还可以优化,比如用 8259A 管理中断,间隔1s产生中断,按键调节时间产生中断。

反馈

有朋友说代码编译后显示没有堆栈段,不知道是不是编译软件的问题,我用 emu8086 v4.08 编译后是可以正常运行的,如果出现上述情况,可以考虑将 STACK SEGMENT 改为 STACKSG SEGMENT STACK.

  • 27
    点赞
  • 184
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不雨_亦潇潇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值