|
;四位数码管时钟显示(24小时),按下RB0后,可以切换到设置, ;同时所有的数字闪烁,按RB1设置小时,按RB2设置分 ;文件名为:TIME.ASM ;作者:牛传宇 ;2006-6 ;************************************** list p=16f84A #include <p16f84A.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 ; COUNT6 EQU 38H ; COUNT8 EQU 39H COUNT9 EQU 40H ;***************************************** ORG 000H ;程序入口 GOTO MAIN ;**************中断服务子程序************* ORG 004H ; TIME ;现场保护 MOVWF W_T ;W送入现场保护寄存器;W、STATUS现场保护 SWAPF STATUS,W ;交换状态寄存器的高低位后 MOVWF ST_T ;送入STATUS的现场保护寄存器 ;初始化TMR0 MOVLW D'100' ;TMR0重赋初值100 MOVWF TMR0 ;送入TMR0定时器 ;清中断溢出标志 BCF INTCON,T0IF ;TMR0中断溢出标志清0 ;先关闭显示 BSF PORTB,0 BSF PORTB,1 BSF PORTB,2 BSF PORTB,3 BSF PORTB,4 BSF PORTB,5 BSF PORTB,6 BCF PORTA,0 ;RA2置1 BCF PORTA,1 ;RA3置1 BCF PORTA,2 ;RA4置1 BCF PORTA,3 ;RA5置1 ;显示位加1 INCF COUNT1,F ;COUNT1加1 ;分钟低位显示检测 MOVLW 01H ;送1到W XORWF COUNT1,W ;把COUNT1与W中的1异或 BTFSC STATUS,Z ;若结果不为0,则跳过下一条指令 GOTO SM ;扫描键盘 GOTO XSJ1 XSJ BSF STATUS,5 MOVLW 00H MOVWF TRISB BCF STATUS,5 BSF PORTB,0 BSF PORTB,1 BSF PORTB,2 BSF PORTB,3 BSF PORTB,4 BSF PORTB,5 BSF PORTB,6 BCF PORTA,0 ;RA2置1 BCF PORTA,1 ;RA3置1 BCF PORTA,2 ;RA4置1 BCF PORTA,3 ;RA5置1 GOTO DISPMIN_L ;COUNT1为1,转分钟低位MIN_L显示 ;分钟高位显示检测 XSJ1 MOVLW 02H ;送2到W XORWF COUNT1,W ;把COUNT1与W中的2异或 BTFSC STATUS,Z ;若结果不为0,则跳过下一条指令 GOTO DISPMIN_H ;COUNT1为2,转分钟高位MIN_H显示 ;小时低位显示检测 MOVLW 03H ;送3到W XORWF COUNT1,W ;把COUNT1与W中的3异或 BTFSC STATUS,Z ;若结果不为0,则跳过下一条指令 GOTO DISPHOU_L ;COUNT1为3,转小时低位HOU_L显示 ;小时高位显示检测 MOVLW 04H ;送4到W XORWF COUNT1,W ;把COUNT1与W中的4异或 BTFSC STATUS,Z ;若结果不为0,则跳过下一条指令 GOTO DISPHOU_H ;COUNT1为4,转小时高位HOU_H显示 ;*****************小时高位HOU_H显示*************************** DISPHOU_H CLRF COUNT1 ;把COUNT1清零 BTFSS FLAG,4 ;检测FLAG的Bit4,为1则跳过下一条指令 GOTO DISP4 ;否则就跳到DIP4 SETDISP4 INCF COUNT5,F ;COUNT5加1 MOVLW D'25' ;送25到W SUBWF COUNT5,W ;COUNT5-W, BTFSS STATUS,C ;检测进位借位标志,若标志为1,则跳过下一条指令 GOTO DISP4 ;COUNT5<25,C=0,转DISP4 MOVLW D'50' ;送50到W XORWF COUNT5,W ;将COUNT5与W异或 BTFSC STATUS,Z ;若结果为0,则执行下一条指令,否则跳过 GOTO M4 ;=50,COUNT5清0,转 ;关闭数码管显示 MOVLW 00H ; MOVWF PORTA ;25<COUNT5<50,小时高位不亮 MOVWF PORTB ; GOTO LOOP2 ; DISP4 ;打开数码管显示 BSF PORTA,3 ;点亮小时高位 BCF PORTA,1 ;关闭小时低位 BCF PORTA,2 ;关闭分钟低位 BCF PORTA,0 ;关闭分钟高位 MOVF HOU_H,W ;小时高位存入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 00H ;25<COUNT5<50,分钟低位不亮 MOVWF PORTB MOVWF PORTA GOTO LOOP2 ; DISP1 BSF PORTA,0 ;点亮分钟低位 BCF PORTA,2 BCF PORTA,3 BCF PORTA,1 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 00H ;25<COUNT5<50,分钟高位不亮 MOVWF PORTA ; MOVWF PORTB GOTO LOOP2 ; DISP2 BSF PORTA,1 ;点亮分钟高位 BCF PORTA,2 BCF PORTA,3 ; BCF PORTA,0 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 PORTB ; BCF PORTA,2 ;点亮小时低位 BCF PORTA,3 BCF PORTA,0 BCF PORTA,1 GOTO LOOP2 ; DISP3 BSF PORTA,2 ;点亮小时低位 BCF PORTA,0 ; BCF PORTA,3 BCF PORTA,1 MOVF HOU_L,W ; CALL CONVERT ; MOVWF PORTB ; ;DP GOTO LOOP2 M3 CLRF COUNT4 GOTO SETDISP3 ;********************显示************************************ DISP CALL CONVERT ;调用查表程序 MOVWF PORTB ;送RC口显示 LOOP2 INCF DIGIT,F ;计数器加1 MOVLW D'100' ; SUBWF DIGIT,W ; BTFSS STATUS,C ; GOTO LOOP11 ;COUNT2<25,C=0 BCF PORTB,7 LOOP12 MOVLW D'200' ;然后与200 XORWF DIGIT,W ;相与,并保存到W BTFSS STATUS,Z ;检测零标志位,如果计数值已到200,则跳过下一步 GOTO TIMEND ;否则跳到中断子程序出口 CLRF DIGIT ;计数器清零 INCF SEC,F ;秒针加1 MOVLW D'60' ;用60 XORWF SEC,W ;和秒针数相与 BTFSS STATUS,Z ;再检测零标志位,如果秒针为60,则跳过下一步 GOTO TIMEND ;否则跳到中断子程序出口 CLRF SEC ;秒针清零 INCF MIN_L,F ;分钟低位加1 MOVLW D'10' ;用10 XORWF MIN_L,W ;和分钟低位相与 BTFSS STATUS,Z ;若结果为0,则会跳过下一步 GOTO TIMEND ;否则跳到中断子程序的出口 CLRF MIN_L ;分钟低位清零 INCF MIN_H,F ;分钟高位加1
MOVLW D'6' ;用6 XORWF MIN_H,W ;和分钟高位相与 BTFSS STATUS,Z ;若结果为0,则会跳过下一步 GOTO TIMEND ;否则跳到中断子程序的出口 CLRF MIN_H ;分钟高位清零
MOVLW D'2' ;用2 XORWF HOU_H,W ;和小时高位相与 BTFSC STATUS,Z ;若结果为0,则执行下一步 GOTO HOU1 ;跳到小时低位检测 INCF HOU_L,F ;小时低位加1
MOVLW D'10' ;用10和 XORWF HOU_L,W ;小时低位相与 BTFSS STATUS,Z ;若结果为0,则会跳过下一步 GOTO TIMEND ;否则跳到中断子程序的出口 CLRF HOU_L ;小时低位清零 INCF HOU_H,F ;小时高位加1 GOTO TIMEND ;跳到中断子程序的出口 LOOP11 BSF PORTB,7 GOTO LOOP12 HOU1 INCF HOU_L,F ;小时低位加1 MOVLW D'4' ;然后用4和 XORWF HOU_L,W ;小时的低位相与 BTFSS STATUS,Z ;若结果为0,则会跳过下一步 GOTO TIMEND ;跳到中断子程序的出口 CLRF HOU_L ;小时低位清零 CLRF HOU_H ;小时高低清零 GOTO TIMEND ;跳到中断子程序的出口 TIMEND ;中断子程序的出口 SWAPF ST_T,W ;先恢复状态寄存器 MOVWF STATUS ; SWAPF W_T,F ;再恢复W SWAPF W_T,W ; RETFIE ; ;**************************************************** CONVERT ADDWF PCL,F ;将W寄存器内的7段显示码地址放入PCL ;PCL执行新地址指令, 跳到相对的地址执行? RETLW H'C0' ;0 ,RETLW指令,将七段显示码存入W后返回 RETLW H'F9' ;1 RETLW H'A4' ;2 RETLW H'B0' ;3 RETLW H'99' ;4 RETLW H'92' ;5 RETLW H'82' ;6 RETLW H'F8' ;7 RETLW H'80' ;8 RETLW H'90' ;9 ;*******************主程序*********************************** MAIN CLRF PORTB ;初始化I/O口 CLRF PORTA ; BSF STATUS,RP0 ;选体1 CLRF TRISA ;定义RA所有相关引脚全部为普通数字I/O脚 MOVLW B'00000100' ; MOVWF OPTION_REG ;启用上拉电阻,定时器分配给TMRO,分频比为1:32 MOVLW 00H MOVWF TRISB BCF STATUS,RP0 ;选体0 ;---------------------------------------------------------- MOVLW D'100' ;定时器送初值100,定时(256-100)*32US=4.992MS MOVWF TMR0 ;每隔4。992MS一次中断 MOVLW 00H ;先熄灭数码管以免闪烁 MOVWF PORTB ; BCF PORTA,2 ; BCF PORTA,3 ; BCF PORTA,0 ; BCF PORTA,1 ; 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 COUNT9 CLRF SEC CLRF FLAG ;------------------------------------------------------------ BCF INTCON,T0IF ;定时器溢出中断标志清0 BSF INTCON,T0IE ;开放总中断和TMR0中断使能 BSF INTCON,GIE ; LOOPX GOTO LOOPX ;等待中断 ;******************分钟/小时调整***************************** SM BSF STATUS,5 MOVLW B'11111111' MOVWF TRISB BCF STATUS,5 LOOP6 BTFSS PORTB,0 ;必须保证RB2松开 CALL DELAY BTFSS PORTB,0 GOTO LOOP7
BTFSS COUNT8,1 GOTO XSJ GOTO LOOP9 LOOP7 BTFSS PORTB,0 GOTO LOOP7 BTFSC COUNT8,1 GOTO QL BSF COUNT8,1 LOOP9 BSF FLAG,4 BSF FLAG,5 LOOP8 BTFSS PORTB,1 CALL DELAY BTFSC PORTB,1 GOTO LOOP10 LOOP15 BTFSS PORTB,1 GOTO LOOP15 INCF MIN_L,1 MOVLW D'10' XORWF MIN_L,W BTFSS STATUS,Z GOTO LOOP8 CLRF MIN_L INCF MIN_H,1 MOVLW 06H XORWF MIN_H,W BTFSS STATUS,Z GOTO LOOP8 CLRF MIN_H GOTO LOOP8 LOOP10 BTFSS PORTB,2 CALL DELAY BTFSC PORTB,2 GOTO XSJ LOOP16 BTFSS PORTB,2 GOTO LOOP16 MOVLW 02H XORWF HOU_H,W BTFSC STATUS,Z GOTO HOU2 INCF HOU_L,1 MOVLW D'10' XORWF HOU_L,W BTFSS STATUS,Z GOTO LOOP10 CLRF HOU_L INCF HOU_H,1 GOTO LOOP10 QL BCF COUNT8,1 BCF FLAG,4 BCF FLAG,5 GOTO XSJ HOU2 INCF HOU_L,1 MOVLW D'4' XORWF HOU_L,W BTFSS STATUS,Z GOTO LOOP10 CLRF HOU_L CLRF HOU_H GOTO LOOP10
;*****************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
|
|