📄 实验27.asm
字号:
;------------------------------------------------------------------------------------------
;在线可调时钟实验参考程序(实验27.asm)
;------------------------------------------------------------------------------------------
LIST P=16F877
INCLUDE "P16F877.INC"
;------------------------------------------------------------------------------------------
TMP_W EQU 70H ;定义变量
TMP_FSR EQU 71H
TMPSTAT EQU 72H
CKMODE EQU 50H ;闹钟工作模式寄存器
FLAG EQU 51H ;标志位寄存器
TMP_CM EQU 52H ;工作模式临时寄存器
CSL EQU 53H ;闹钟秒的低位寄存器
CSH EQU 54H ;闹钟秒的高位寄存器
CML EQU 55H ;闹钟分钟的低位寄存器
CMH EQU 56H ;闹钟分钟的高位寄存器
CHL EQU 57H ;闹钟小时的低位寄存器
CHH EQU 58H ;闹钟小时的高位寄存器
SL EQU 59H ;时钟秒的低位寄存器
SH EQU 5AH ;时钟秒的高位寄存器
ML EQU 5BH ;时钟分钟的低位寄存器
MH EQU 5CH ;时钟分钟的高位寄存器
HL EQU 5DH ;时钟小时的低位寄存器
HH EQU 5EH ;时钟小时的高位寄存器
;------------------------------------------------------------------------------------------
ORG 0000H
NOP
GOTO MAIN ;跳转至主函数
;------------------------------------------------------------------------------------------
;中断处理子程序
;------------------------------------------------------------------------------------------
ORG 0004H
INTRPT MOVWF TMP_W ;保护W寄存器
SWAPF TMP_W,F
SWAPF STATUS,W ;保护状态寄存器STATUS
MOVWF TMPSTAT
MOVF FSR,W ;保护间接寻址寄存器FSR
MOVWF TMP_FSR
BCF T1CON,0 ;关闭定时器1
MOVLW 0C0H ;设定定时器1的时间为500ms
MOVWF TMR1H
MOVLW 0CH
MOVLW TMR1L
BSF T1CON,0 ;重新开启定时器1
BCF PIR1,TMR1IF ;清除中断标志位
MOVLW 01H
XORWF FLAG,F ;标志位寄存器第0位取反
BTFSC FLAG,0 ;判断是否已过1s
GOTO INTNXT0 ;若不是,则跳转至INTNXT0
MOVLW SL
MOVWF FSR
CALL ADDSORM ;时钟的秒加1
BTFSS FLAG,7 ;判断是否有进位
GOTO INTNXT0 ;若没有,则跳转至INTNXT0
MOVLW ML
MOVWF FSR
CALL ADDSORM ;时钟的分钟加1
BTFSS FLAG,7 ;判断是否有进位
GOTO INTNXT0 ;若没有,则跳转至INTXT0
MOVLW HL
MOVWF FSR
CALL ADDHOUR ;时钟的小时加1
INTNXT0 BTFSC CKMODE,3 ;判断时钟是否正处于工作模式3
GOTO INTM3 ;若是,则跳转至INTM3
BTFSC CKMODE,2 ;判断时钟是否正处于工作模式2
GOTO INTM2 ;若是,则跳转至INTM2
;------------------------------------------------------------------------------------------
;工作模式0或1时的中断处理子程序
;------------------------------------------------------------------------------------------
INTM01 MOVLW 0AH
MOVWF 62H ;显示缓冲寄存器62H、65H置0AH
MOVWF 65H
INTM0D MOVF HH,W ;时钟小时的高位HH送显示缓冲寄存器67H
MOVWF 67H
MOVF HL,W ;时钟小时的低位HL送显示缓冲寄存器66H
MOVWF 66H
MOVF MH,W ;时钟分钟的高位ML送显示缓冲寄存器64H
MOVWF 64H
MOVF ML,W ;时钟分钟的低位ML送显示缓冲寄存器63H
MOVWF 63H
MOVF SH,W ;时钟秒的高位SH送显示缓冲寄存器61H
MOVWF 61H
MOVF SL,W ;时钟秒的低位SL送显示缓冲寄存器60H
MOVWF 60H
BTFSC CKMODE,1 ;判断闹钟当前的工作模式是否为模式1
GOTO TDARK ;若是,则跳转TDARK
GOTO OUTINT ;若不是,则跳转OUTINT
;------------------------------------------------------------------------------------------
;工作模式3时的中断处理子程序
;------------------------------------------------------------------------------------------
INTM3 MOVF HH,W ;比较当前的时钟值与闹铃值是否相等
SUBWF CHH,W
BTFSS STATUS,Z
GOTO INTM30 ;若小时的高位不相等,则跳转至INTM30
MOVF HL,W
SUBWF CHL,W
BTFSS STATUS,Z
GOTO INTM30 ;若小时的低位不相等,则跳转至INTM30
MOVF MH,W
SUBWF CMH,W
BTFSS STATUS,Z
GOTO INTM30 ;若分钟的高位不相等,则跳转至INTM30
MOVF ML,W
SUBWF CML,W
BTFSS STATUS,Z
GOTO INTM30 ;若分钟的低位不相等,则跳转至INTM30
MOVF SH,W
SUBWF CSH,W
BTFSS STATUS,Z
GOTO INTM30 ;若秒的高位不相等,则跳转至INTM30
MOVF SL,W
SUBWF CSL,W
BTFSS STATUS,Z
GOTO INTM30 ;若秒的低位不相等,则跳转至INTM30
BSF PORTD,7 ;若相等,则开启蜂鸣器
INTM30 MOVLW 0BH
MOVWF 62H ;显示缓冲寄存器分别送“-”的编码号
MOVWF 65H
GOTO INTM0D ;跳转至INTM0D
;------------------------------------------------------------------------------------------
;工作模式2时的中断处理子程序
;------------------------------------------------------------------------------------------
INTM2 MOVLW 0BH
MOVWF 62H ;显示缓冲寄存器分别送“-”的编码号
MOVWF 65H
MOVF CHH,W ;取闹铃时间小时的高位到显示缓冲寄存器67H
MOVWF 67H
MOVF CHL,W ;取闹铃时间小时的低位到显示缓冲寄存器66H
MOVWF 66H
MOVF CMH,W ;取闹铃时间分钟的高位到显示缓冲寄存器64H
MOVWF 64H
MOVF CML,W ;取闹铃时间分钟的低位到显示缓冲寄存器63H
MOVWF 63H
MOVF CSH,W ;取闹铃时间秒的低位到显示缓冲寄存器61H
MOVWF 61H
MOVF CSL,W ;取闹铃时间秒的低位到显示缓冲寄存器60H
MOVWF 60H
TDARK MOVLW 0AH ;立即数0AH到W
BTFSS FLAG,0 ;判断1S是否已到
GOTO OUTINT ;若没到,则跳转到OUTINT
BTFSC CKMODE,5 ;判断是否正在调整小时
GOTO HDARK ;若是,则跳转至HDARK
BTFSC CKMODE,6 ;判断是否正在调整分钟
GOTO MDARK ;若是,则跳转至MDARK
SDARK MOVWF 60H ;把W的内容送显示缓冲寄存器60H、61H
MOVWF 61H
GOTO OUTINT ;跳转至OUTINT
MDARK MOVWF 63H ;把W的内容送显示缓冲寄存器63H、64H
MOVWF 64H
GOTO OUTINT ;跳转至OUTINT
HDARK MOVWF 66H ;把W的内容送显示缓冲寄存器66H、67H
MOVWF 67H
GOTO OUTINT ;跳转至OUTINT
;------------------------------------------------------------------------------------------
;显示及退出中断子程序
;------------------------------------------------------------------------------------------
OUTINT MOVLW 67H ;设置显示缓冲器的数据地址
MOVWF FSR
LOOP MOVF INDF,W ;取出数据
CALL BMA ;查询对应编码
CALL SPIOUT ;利用SPI方式输出编码数据
DECF FSR
BTFSS FSR,3 ;判断8位数码是否已全部输出
GOTO LOOP ;若没有,则跳转至LOOP
MOVF TMP_FSR,W ;还原FSR寄存器的内容
MOVWF FSR
SWAPF TMPSTAT,W ;还原STATUS寄存器的内容
MOVWF STATUS
SWAPF TMP_W,W ;还原W寄存器中的内容
RETFIE
;------------------------------------------------------------------------------------------
;SPI方式输出编码子程序
;------------------------------------------------------------------------------------------
SPIOUT MOVWF SSPBUF ;读取编码到SPI缓冲器
BSF STATUS,RP0 ;转到体1
LP BTFSS SSPSTAT,BF ;是否发送完毕
GOTO LP ;继续发送
BCF STATUS,RP0 ;返回体0
MOVF SSPBUF,W ;读取一个无效字符
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
;编码
;------------------------------------------------------------------------------------------
BMA ADDWF PCL,F
RETLW 3FH ;"0"
RETLW 06H ;"1"
RETLW 5BH ;"2"
RETLW 4FH ;"3"
RETLW 66H ;"4"
RETLW 6DH ;"5"
RETLW 7DH ;"6"
RETLW 07H ;"7"
RETLW 7FH ;"8"
RETLW 6FH ;"9"
RETLW 00H ;dark
RETLW 40H ;"-"
;------------------------------------------------------------------------------------------
;主程序
;------------------------------------------------------------------------------------------
MAIN BSF STATUS,RP0 ;转到体1
BSF INTCON,PEIE ;打开外部中断使能位
BSF PIE1,TMR1IE ;打开TMR1中断
MOVLW B'00010010'
MOVWF TRISC ;设置C口方向控制字
MOVLW 0FH
MOVWF TRISD ;设置D口方向控制字
MOVLW B'00000000'
MOVWF SSPSTAT
BCF STATUS,RP0 ;转回体0
MOVLW B'00110000'
MOVWF SSPCON
CHUSH MOVLW B'00100001' ;设置闹钟的工作模式状态字
MOVWF CKMODE
CLRF FLAG ;进位标志位清0
BCF PORTD,7 ;闹铃关
MOVLW CSL ;闹铃秒的低位地址到FSR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -