//*APPLICATION NOTE E6000 ICEXPLORER ***************
//* Title: FOR colk_time *
//* Version: 00 *
//* Last Updated: *
//* MCU: PIC16F877A *
//* FOR: WWW.PICAVR.COM *
//***************************************************
;四位数码管时钟显示(24小时),按下RB1后按RB2小时闪烁,调整小时,再次按下RB1
;按RB2分钟闪烁调整分钟,再按RB1小时、分钟不闪烁,退出小时分钟调整。
;**************************************
list p=16f877A
#include <p16f877A.inc>
;************变量定义******************
DIGIT EQU 20H ;5MS计数器
MIN_L EQU 21H ;分钟
MIN_H EQU 22H ;
HOU_L EQU 23H ;小时
HOU_H EQU 24H ;
SEC EQU 25H ;秒位
FLAG EQU 26H ;第4位为小时调整标志位,第5位为分钟调整标志位
W_T EQU 27H ;W现场保护寄存器
ST_T EQU 28H ;STATUS现场保护寄存器
TABADD EQU 29H ;转换数码管地址
C1 EQU 30H ;
C2 EQU 31H ;
COUNT1 EQU 33H ;
COUNT2 EQU 34H ;
COUNT3 EQU 35H ;
COUNT4 EQU 36H ;
COUNT5 EQU 37H ;
;*****************************************
ORG 000H
GOTO MAIN
;**************中断服务子程序*************
ORG 004H ;
TIME
MOVWF W_T ;W、STATUS现场保护
SWAPF STATUS,W ;
MOVWF ST_T ;
MOVLW D'100' ;TMR0重赋初值
MOVWF TMR0 ;
BCF INTCON,T0IF ;TMR0中断溢出标志清0
MOVLW 0FFH ;先熄灭数码管以免闪烁
MOVWF PORTC ;
BSF PORTA,2
BSF PORTA,3 ;
BSF PORTA,4
BSF PORTA,5
INCF COUNT1,F ;
MOVLW 01H ;
XORWF COUNT1,W
BTFSC STATUS,Z ;
GOTO DISPMIN_L ;COUNT1为1,转分钟低位MIN_L显示
MOVLW 02H ;
XORWF COUNT1,W ;
BTFSC STATUS,Z ;
GOTO DISPMIN_H ;COUNT1为2,转分钟高位MIN_H显示
MOVLW 03H ;
XORWF COUNT1,W ;
BTFSC STATUS,Z ;
GOTO DISPHOU_L ;COUNT1为3,转小时低位HOU_L显示
;*********************小时高位HOU_H显示*******************************
MOVLW 04H ;
XORWF COUNT1,W ;
BTFSC STATUS,Z ;
GOTO DISPHOU_H ;COUNT1为4,转小时低位HOU_H显示
DISPHOU_H CLRF COUNT1
BTFSS FLAG,4
GOTO DISP4
SETDISP4
INCF COUNT5,F ;
MOVLW D'25' ;
SUBWF COUNT5,W ;COUNT5-W,
BTFSS STATUS,C ;
GOTO DISP4 ;COUNT5<25,C=0,转DISP4
MOVLW D'50' ;
XORWF COUNT5,W ;
BTFSC STATUS,Z ;
GOTO M4 ;=50,COUNT5清0,转
MOVLW 0FFH
MOVWF PORTA ;25<COUNT5<50,小时高位不亮
MOVWF PORTC
GOTO LOOP2 ;
DISP4
BCF PORTA,3 ;点亮小时高位
BSF PORTA,2
BSF PORTA,4
BSF PORTA,5
MOVF HOU_H,W ;
GOTO DISP
M4
CLRF COUNT5
GOTO SETDISP4
;*****************分钟低位MIN_L显示***************************
DISPMIN_L
BTFSS FLAG,5 ;
GOTO DISP1 ;分钟不调整,转DISP1
SETDISP1
INCF COUNT2,F ;
MOVLW D'25' ;
SUBWF COUNT2,W ;
BTFSS STATUS,C ;
GOTO DISP1 ;COUNT2<25,C=0
MOVLW D'50' ;
XORWF COUNT2,W ;
BTFSC STATUS,Z ;
GOTO M1 ;=50,COUNT2清0,转点亮分钟低位
MOVLW 0FFH ;25<COUNT5<50,分钟低位不亮
MOVWF PORTC
MOVWF PORTA
GOTO LOOP2 ;
DISP1
BCF PORTA,4 ;点亮分钟低位
BSF PORTA,2
BSF PORTA,3
BSF PORTA,5
MOVF MIN_L,W ;
GOTO DISP ;
M1
CLRF COUNT2
GOTO SETDISP1
;*********************分钟高位MIN_H显示********************************
DISPMIN_H
BTFSS FLAG,5 ;
GOTO DISP2 ;
SETDISP2
INCF COUNT3,F ;
MOVLW D'25' ;
SUBWF COUNT3,W ;
BTFSS STATUS,C ;
GOTO DISP2 ;
MOVLW D'50' ;
XORWF COUNT3,W ;
BTFSC STATUS,Z ;
GOTO M2
MOVLW 0FFH ;25<COUNT5<50,分钟高位不亮
MOVWF PORTA ;
MOVWF PORTC
GOTO LOOP2 ;
DISP2
BCF PORTA,5 ;点亮分钟高位
BSF PORTA,2
BSF PORTA,3 ;
BSF PORTA,4
MOVF MIN_H,W ;
GOTO DISP ;
M2
CLRF COUNT3
GOTO SETDISP2
;*********************小时低位HOU_L显示******************************
DISPHOU_L
BTFSS FLAG,4 ;
GOTO DISP3 ;
SETDISP3
INCF COUNT4,F ;
MOVLW D'25' ;
SUBWF COUNT4,W ;
BTFSS STATUS,C ;
GOTO DISP3 ;
MOVLW D'50' ;
XORWF COUNT4,W ;
BTFSC STATUS,Z ;
GOTO M3
MOVLW B'01111111' ;
MOVWF PORTC ;
BCF PORTA,2 ;点亮小时低位
BSF PORTA,3
BSF PORTA,4
BSF PORTA,5
GOTO LOOP2 ;
DISP3
BCF PORTA,2 ;点亮小时低位
BSF PORTA,3 ;
BSF PORTA,4
BSF PORTA,5
MOVF HOU_L,W ;
CALL CONVERT ;
MOVWF PORTC ;
BCF PORTC,7 ;DP
GOTO LOOP2
M3
CLRF COUNT4
GOTO SETDISP3
;********************显示************************************
DISP
CALL CONVERT ;
MOVWF PORTC ;送RC口显示
LOOP2
INCF DIGIT,F
MOVLW D'200' ;
XORWF DIGIT,W ;
BTFSS STATUS,Z ;
GOTO TIMEND ;
CLRF DIGIT ;
INCF SEC,F ;
MOVLW D'60' ;
XORWF SEC,W ;
BTFSS STATUS,Z ;
GOTO TIMEND ;
CLRF SEC ;
INCF MIN_L,F
MOVLW D'10' ;
XORWF MIN_L,W ;
BTFSS STATUS,Z ;
GOTO TIMEND ;
CLRF MIN_L
INCF MIN_H,F ;
MOVLW D'6' ;
XORWF MIN_H,W ;
BTFSS STATUS,Z ;
GOTO TIMEND ;
CLRF MIN_H ;
MOVLW D'2' ;
XORWF HOU_H,W ;
BTFSC STATUS,Z ;
GOTO HOU1 ;
INCF HOU_L,F ;
MOVLW D'10'
XORWF HOU_L,W ;
BTFSS STATUS,Z ;
GOTO TIMEND ;
CLRF HOU_L ;
INCF HOU_H,F ;
GOTO TIMEND ;
HOU1
INCF HOU_L,F
MOVLW D'4' ;
XORWF HOU_L,W ;
BTFSS STATUS,Z
GOTO TIMEND ;
CLRF HOU_L
CLRF HOU_H ;
GOTO TIMEND ;
TIMEND
SWAPF ST_T,W
MOVWF STATUS
SWAPF W_T,F
SWAPF W_T,W
RETFIE
;****************************************************
CONVERT
ADDWF PCL,F ;将W寄存器内的7段显示码地址放入PCL ;PCL执行新地址指令, 跳到相对的地址执行?
RETLW 0C0H ;0 ,RETLW指令,将七段显示码存入W后返回
RETLW 0F9H ;1
RETLW 0A4H ;2
RETLW 0B0H ;3
RETLW 099H ;4
RETLW 092H ;5
RETLW 082H ;6
RETLW 0F8H ;7
RETLW 080H ;8
RETLW 090H ;9
;*******************主程序***********************************
MAIN
CLRF PORTC ;初始化I/O口
CLRF PORTA ;
BSF STATUS,RP0 ;选体1
MOVLW 06H
MOVWF ADCON1 ;定义RA所有相关引脚全部为普通数字I/O脚
MOVLW 00H ;RA、RC定义为输出
MOVWF TRISC ;
MOVWF TRISA ;
MOVLW 0FFH ;RB定义为输入
MOVWF TRISB ;
MOVLW B'00000100' ;
MOVWF OPTION_REG ;启用上拉电阻,定时器分配给TMRO,分频比为1:32
BCF STATUS,RP0 ;选体0
MOVLW D'100' ;定时器送初值100,定时(256-100)*32US=4.992MS
MOVWF TMR0 ;每隔4。992MS一次中断
MOVLW 0FFH ;先熄灭数码管以免闪烁
MOVWF PORTC ;
BSF PORTA,2
BSF PORTA,3 ;
BSF PORTA,4
BSF PORTA,5
CLRF DIGIT
CLRF MIN_L
CLRF MIN_H
CLRF HOU_L
CLRF HOU_H
CLRF COUNT1
CLRF COUNT2
CLRF COUNT3
CLRF COUNT4
CLRF COUNT5
CLRF SEC
CLRF FLAG
BCF INTCON,T0IF ;定时器溢出中断标志清0
BSF INTCON,T0IE ;开放总中断和TMR0中断使能
BSF INTCON,GIE ;
;******************分钟/小时调整*****************************
LOOP6 BTFSS PORTB,2 ;必须保证RB2松开
GOTO LOOP6
CALL DELAY
BTFSS PORTB,2
GOTO LOOP6
LOOP7 BTFSS PORTB,1 ;RB1是否松开?
GOTO LOOP7
CALL DELAY
BTFSS PORTB,1
GOTO LOOP7
LOOP
BCF FLAG,4 ;小时调整标志位清0
BCF FLAG,5 ;分钟调整标志位清0
LOOP1
BTFSC PORTB,1 ;RB1按下否?
GOTO LOOP1 ;
CALL DELAY ;
BTFSC PORTB,1 ;再判RB1按下否?
GOTO LOOP1
;********************小时调整***********************************
BSF FLAG,4 ;小时调整标志位置1
LOOP3 BTFSS PORTB,1 ;RB1是否松开?不松开不允许执行RB2按下
GOTO LOOP3
CALL DELAY
BTFSS PORTB,1
GOTO LOOP3
SET_1 BTFSC PORTB,2 ;RB2按下否?
GOTO CLOCK1 ;未按下
CALL DELAY
BTFSC PORTB,2
GOTO CLOCK1
MOVLW 02H
XORWF HOU_H,W
BTFSC STATUS,Z
GOTO HOU2 ;小时高位等于2转HOU2
INCF HOU_L,F ;不等于2,小时低位加1
MOVLW D'10'
XORWF HOU_L,W
BTFSS STATUS,Z
GOTO CLOCK1 ;小时低位不等于10,等待RB2再次按下
CLRF HOU_L ;等于10小时低位清0,
INCF HOU_H,F ;小时高位加1
;等待再次按RB2
CLOCK1
BTFSC PORTB,1 ;CLOCK按下否?
GOTO SET_1 ;CLOCK未按下,判断SET是否按下?
CALL DELAY
BTFSC PORTB,1
GOTO SET_1
GOTO LOOP5 ;CLOCK按下进行分钟调整
HOU2
INCF HOU_L,F ;小时低位加1
MOVLW D'4' ;
XORWF HOU_L,W ;
BTFSS STATUS,Z
GOTO CLOCK1 ;小时低位不等于4
CLRF HOU_L ;小时低位等于4,小时高低位清0,等待RB2按下
CLRF HOU_H ;
GOTO CLOCK1
;*******************分钟调整********************************
LOOP5 BTFSS PORTB,2 ;必须保证RB2松开
GOTO LOOP5
CALL DELAY
BTFSS PORTB,2
GOTO LOOP5
BCF FLAG,4 ;小时调整标志位清0
BSF FLAG,5 ;分钟调整标志位置1
LOOP4 BTFSS PORTB,1 ;RB1是否松开?不松开不允许执行RB2按下
GOTO LOOP4
CALL DELAY
BTFSS PORTB,1
GOTO LOOP4
SET_2 BTFSC PORTB,2 ;RB2按下?
GOTO CLOCK2 ;未按下
CALL DELAY
BTFSC PORTB,2
GOTO CLOCK2
INCF MIN_L,F ;RB2按下,分钟低位加1
MOVLW D'10'
XORWF MIN_L,W
BTFSS STATUS,Z
GOTO CLOCK2 ;不等于10,
CLRF MIN_L ;等于10,分钟低位清0
INCF MIN_H,F ;高位加1
MOVLW 06H
XORWF MIN_H,W
BTFSS STATUS,Z
GOTO CLOCK2
CLRF MIN_H ;等于6,分钟高位清0
;等待RB2再次按下
CLOCK2
BTFSC PORTB,1 ;CLOCK按下否?
GOTO SET_2 ;CLOCK未按下,判断SET是否按下?
CALL DELAY
BTFSC PORTB,1
GOTO SET_2
GOTO LOOP6
;*****************0.1S延时子程序*******************
DELAY
MOVLW D'150'
MOVWF C1
L2
MOVLW D'255'
MOVWF C2
L3
DECFSZ C2,F
GOTO L3
DECFSZ C1,F
GOTO L2
RETLW 0
;****************************************************
END