实验27.asm
来自「实验27-在线可调时钟实验参考程序,基于PIC16F877A」· 汇编 代码 · 共 431 行 · 第 1/2 页
ASM
431 行
MOVWF FSR
CLEAR CLRF INDF ;INDF指向的寄存器清0
INCF FSR,F ;FSR加1
MOVLW HH+1 ;时钟小时的高位地址加1到W
SUBWF FSR,W
BTFSS STATUS,Z ;判断FSR的内容是否与时钟的高位相一致
GOTO CLEAR ;跳转至CLEAR
MOVLW 0AH ;立即数0AH送W
MOVWF 60H ;送W中的内容至显示缓冲寄存器60H-67H
MOVWF 61H
MOVWF 62H
MOVWF 63H
MOVWF 64H
MOVWF 65H
MOVWF 66H
MOVWF 67H
BSF INTCON,GIE ;打开总中断
MOVLW 0C0H ;设置TMR1的初值
MOVWF TMR1H
CLRF TMR1L
MOVLW B'00001011' ;设置TMR1的控制字
MOVWF T1CON
;------------------------------------------------------------------------------------------
;键盘扫描子程序
;------------------------------------------------------------------------------------------
RD0 BTFSS PORTD,0 ;判断按键0是否被按下
GOTO RD1 ;若没有,则跳转至RD1,继续扫描
CALL YS5MS ;若被按下,则调用5ms延时子程序,防止抖动
BTFSS PORTD,0 ;再次判断按键0是否被按下
GOTO RD1 ;若没有,则跳转至RD1,继续扫描
PD0 BTFSC PORTD,0 ;若被按下,则判断按键0是否被放开
GOTO PD0 ;若没有,则跳转至PD0,等待其被放开
CALL YS5MS ;若被放开,则调用5ms延时子程序,防止抖动
BTFSC PORTD,0 ;再次判断按键0是否被放开
GOTO PD0 ;若没有,则跳转至PD0,等待其被放开
CALL KEY0 ;调用按键0处理子程序
RD1 BTFSS PORTD,1
GOTO RD2
CALL YS5MS
BTFSS PORTD,1
GOTO RD2
PD1 BTFSC PORTD,1
GOTO PD1
CALL YS5MS
BTFSC PORTD,1
GOTO PD1
CALL KEY1 ;调用按键1处理子程序
RD2 BTFSS PORTD,2
GOTO RD3
CALL YS5MS
BTFSS PORTD,2
GOTO RD3
PD2 BTFSC PORTD,2
GOTO PD2
CALL YS5MS
BTFSC PORTD,2
GOTO PD2
CALL KEY2 ;调用按键2处理子程序
RD3 BTFSS PORTD,3
GOTO RD0
CALL YS5MS
BTFSS PORTD,3
GOTO RD0
PD3 BTFSC PORTD,3
GOTO PD3
CALL YS5MS
BTFSC PORTD,3
GOTO PD3
BCF PORTD,7 ;关闭闹铃
GOTO RD0 ;循环扫描
;------------------------------------------------------------------------------------------
;按键0处理子程序
;------------------------------------------------------------------------------------------
KEY0 BTFSC CKMODE,0 ;判断闹钟的工作模式是否为模式0
GOTO K0M0 ;若是,则跳转至K0M0
BTFSC CKMODE,1 ;判断闹钟的工作模式是否为模式1
GOTO K0M1 ;若是,则跳转至K0M1
BTFSC CKMODE,2 ;判断闹钟的工作模式是否为模式2
GOTO K0M2 ;若是,则跳转至K0M2
K0M3 MOVLW B'00100001' ;设置工作模式0的状态字到CKMODE
MOVWF CKMODE
RETURN ;子程序返回
K0M2 MOVLW B'00101000' ;设置工作模式3的状态字到CKMODE
MOVWF CKMODE
RETURN ;子程序返回
K0M1 MOVLW B'00100100' ;设置工作模式2的状态字到CKMODE
MOVWF CKMODE
RETURN ;子程序返回
K0M0 MOVLW B'00100010' ;设置工作模式1的状态字到CKMODE
MOVWF CKMODE
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
;按键1处理子程序
;------------------------------------------------------------------------------------------
KEY1 BTFSC CKMODE,0 ;判断闹钟的工作模式是否为普通模式
RETURN ;若是,则子程序返回
BTFSC CKMODE,3 ;判断闹钟的工作模式是否为闹钟模式
RETURN ;若是,则子程序返回
MOVLW 0F0H ;立即数0F0H送W
ANDWF CKMODE,W ;工作模式寄存器CKMODE与W相与,结果送W
MOVWF TMP_CM ;W中的内容送工作模式临时寄存器TMP_CM
BCF STATUS,C ;STATUS的进位位C清0
RLF TMP_CM ;左移工作模式临时寄存器TMP_CM
BTFSS STATUS,C ;判断STATUS的进位位C是否为1
GOTO K1T0 ;若不是,则跳转至K1T0
MOVF CKMODE,W ;CKMODE中的内容送W
ANDLW 0FH ;W与立即数0FH相与
MOVWF TMP_CM ;W中的内容送TMP_CM
BSF TMP_CM,5 ;TMP_CM的第5位置1
MOVF TMP_CM,W ;TMP_CM中的内容送W
MOVWF CKMODE ;W中的内容送CKMODE
RETURN ;子程序返回
K1T0 MOVLW 0FH ;立即数0FH送W
ANDWF CKMODE,W ;CKMODE中的内容与W相与,结果送W
IORWF TMP_CM,W ;W与TMP_CM的内容相或
MOVWF CKMODE ;把W中的内容送CKMODE
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
;按键2处理子程序
;------------------------------------------------------------------------------------------
KEY2 BTFSS CKMODE,1 ;判断是否是调整时间模式
GOTO K2T0 ;若不是,则跳转K2T0
BTFSC CKMODE,5 ;判断是否是调整小时
GOTO K2TT1 ;若是,则跳转至K2TT1
BTFSC CKMODE,6 ;判断是否是调整分钟
GOTO K2TT2 ;若是,则跳转至K2TT2
K2TT3 MOVLW SL ;取秒的寄存器低位SL地址到W
GOTO ADSSMM ;跳转至ADSSMM
K2TT2 MOVLW ML ;取分钟的寄存器低位ML地址到W
ADSSMM MOVWF FSR ;把W内的内容放入FSR
CALL ADDSORM ;调用秒或分钟加1子程序ADDSORM
RETURN ;子程序返回
K2TT1 MOVLW HL ;取小时的寄存器低位HL地址到W
K2H MOVWF FSR ;把W内的内容放入FSR
CALL ADDHOUR ;调用小时加1子程序ADDHOUR
RETURN ;子程序返回
K2T0 BTFSS CKMODE,2 ;判断是否为调整闹铃模式
RETURN ;若不是则,子程序返回
BTFSC CKMODE,5 ;判断是否为调整小时
GOTO K2TC1 ;若是,则跳转至K2TC1
BTFSC CKMODE,6 ;判断是否为调整分钟
GOTO K2TC2 ;若是,则跳转至K2TC2
K2TC3 MOVLW CSL ;取秒的寄存器低位CSL地址到W
GOTO ADSSMM ;跳转至ADDSSMM
K2TC2 MOVLW CML ;取分钟的寄存器低位CML地址到W
GOTO ADSSMM ;跳转至ADDSSMM
K2TC1 MOVLW CHL ;取小时的寄存器低位CHL地址到W
GOTO K2H ;跳转至K2H
;------------------------------------------------------------------------------------------
;分钟或秒加1子程序
;------------------------------------------------------------------------------------------
ADDSORM BCF FLAG,7 ;进位标志FLAG清0
MOVF INDF,W ;取分钟或秒的个位到W
SUBLW 09H
BTFSC STATUS,Z ;判断是否等于9
GOTO GWJW ;若是,则跳转至GWJW
INCF INDF ;个位加1
RETURN ;子程序返回
GWJW CLRF INDF ;个位清0
INCF FSR ;FSR指向分钟或秒的十位
MOVF INDF,W ;取分钟或秒的十位到W
SUBLW 05H
BTFSC STATUS,Z ;判断是否等于5
GOTO SWJW ;若是,则跳转至SWJW
INCF INDF,F ;十位加1
RETURN ;子程序返回
SWJW BSF FLAG,7 ;进位标志位FLAG置1
CLRF INDF ;十位清0
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
;小时加1子程序
;------------------------------------------------------------------------------------------
ADDHOUR MOVF INDF,W ;取INDF中内容到W(小时的个位)
SUBLW 03H ;
BTFSC STATUS,Z ;判断小时的个位是否为3
GOTO HOUR3 ;若是,则跳转至HOUR3
HOUR0 MOVF INDF,W ;取INDF中内容到W(小时的个位)
SUBLW 09H
BTFSC STATUS,Z ;判断小时的个位是否为9
GOTO HOUR9 ;若是,则跳转至HOUR9
HOURN INCF INDF,F ;小时的个位加1
RETURN ;子程序返回
HOUR3 INCF FSR ;FSR指向小时的十位
MOVF INDF,W ;取INDF中内容到W(小时的十位)
SUBLW 02H
BTFSS STATUS,Z ;判断小时的十位是否为2
GOTO HOUR1 ;若不是,则跳转至HOUR1
CLRF INDF ;小时的十位清0
DECF FSR ;FSR指向小时的个位
CLRF INDF ;小时的个位清0
RETURN ;子程序返回
HOUR1 DECF FSR ;FSR指向小时的个位
GOTO HOURN ;跳转至HOURN
HOUR9 CLRF INDF ;小时的个位清0
INCF FSR ;FSR指向小时的十位
INCF INDF ;小时的十位加1
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
;5ms延时子程序
;------------------------------------------------------------------------------------------
YS5MS MOVLW .135 ;外循环常数
MOVWF 20H ;外循环寄存器
Y5MSW MOVLW .11 ;内循环常数
MOVWF 21H ;内循环寄存器
Y5MSN DECFSZ 21H,1 ;内循环寄存器递减
GOTO Y5MSN ;继续内循环
DECFSZ 20H,1 ;外循环寄存器递减
GOTO Y5MSW ;继续外循环
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
END
;------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?