PIC編的數字鐘(轉nee)用PIC編的數字鐘,希望對大家有所幫助?。?!
;******************************************* ;數字鐘程序 ;******************************************* LIST P=16F877 INCLUDE BCDMIAO EQU 70H;存放秒的二進制轉化為BCD后的BCD嗎 BCDFEN EQU 71H;存分的 BCDSHI EQU 72H;存十的 GMIAO EQU 73H;秒個位寄存器 SMIAO EQU 74H;十位 GFEN EQU 75H;分個位寄存器 SFEN EQU 76H;十位 GSHI EQU 77H;時個位寄存器 SSHI EQU 78H;十位 COUNT EQU 79H;計數器 DY1 EQU 7AH;延時計數器1 DY2 EQU 7BH;延時計數器2 WTEMP EQU 7CH;W備份寄存器 STEMP EQU 7DH;STATUS備份寄存器 TEMP EQU 7EH;定時器0初值寄存器 RBTEMP EQU 7FH;RB口寄存器 DY5 EQU 20H;延時計數器5 DY6 EQU 21H;6 PCLATH_TEMP EQU 22H;PCLATH備份寄存器 DISPBUF EQU 24H ;顯示值暫存 DISPBUF_H EQU 25H ;顯示器高位 DISPBUF_L EQU 26H ;顯示器低位 BUFFER EQU 27H;移位寄存器(之所以這樣稱呼它,是應為BUFFER1中得數左移到它中) BUFFER1 EQU 28H;存放個/分/時的數據(可對它進行移位) SUM EQU 29H;判斷寄存器(判斷高低四位加三后是否大于7) DIGHT EQU 2AH ;存放個/分/時的數據(中轉寄存器) CMIAO EQU 30H;存秒的數(二進制) CFEN EQU 31H;分的 CSHI EQU 32H;時的 COUNTER EQU 33H
;主程序 ORG 0000H GOTO MAIN ORG 0004H GOTO SERVE ORG 0005H MAIN NOP; BCF STATUS,RP0; MOVLW 00H;P口清0 MOVWF PORTC; BSF STATUS,RP0; MOVLW 00H ;P口輸出 MOVWF TRISC; MOVLW 0FFH; MOVWF TRISB; MOVLW 47H;INT上升沿觸發,分頻器為TMR0,1:256 MOVWF OPTION_REG; BCF STATUS,RP0; MOVLW 0F8H;開中斷 MOVWF INTCON; BCF INTCON,T0IF;清標志位 BCF INTCON,INTF; BCF INTCON,RBIF; CLRF CMIAO;清存寄存器 CLRF CFEN; CLRF CSHI; MOVLW D'20';設置定時期的中斷次數 MOVWF COUNT; MOVLW D'60';定時期初值 MOVWF TEMP; MOVWF TMR0;開定時期
循環掃描程序 SHAOMIAO BCF STATUS,RP0; MOVF CMIAO,0; MOVWF DIGHT;秒位數據送出轉換為BCD碼 CALL BCD2; MOVWF BCDMIAO;帶會BCD碼 MOVWF GMIAO;給秒的個位積存器 MOVLW 0FH;屏蔽高四位 ANDWF GMIAO; MOVLW 50H;位選碼 IORWF GMIAO;BCD碼+位選 MOVF GMIAO,0; MOVWF PORTC;送顯 CALL YANSHI; MOVF BCDMIAO,0;同上 MOVWF SMIAO; MOVLW 0F0H; ANDWF SMIAO,1; SWAPF SMIAO,1;注意此處要反轉 MOVLW 40H; IORWF SMIAO; MOVF SMIAO,0; MOVWF PORTC; CALL YANSHI; MOVF CFEN,0;同上 MOVWF DIGHT; CALL BCD2; MOVWF BCDFEN; MOVWF GFEN; MOVLW 0FH; ANDWF GFEN; MOVLW 30H; IORWF GFEN; MOVF GFEN,0; MOVWF PORTC; CALL YANSHI; MOVF BCDFEN,0; MOVWF SFEN; MOVLW 0F0H; ANDWF SFEN; SWAPF SFEN; MOVLW 20H; IORWF SFEN; MOVF SFEN,0; MOVWF PORTC; CALL YANSHI; MOVF CSHI,0; MOVWF DIGHT; CALL BCD2; MOVWF BCDSHI; MOVWF GSHI; MOVLW 0FH; ANDWF GSHI; MOVLW 10H; IORWF GSHI; MOVF GSHI,0; MOVWF PORTC; CALL YANSHI; MOVF BCDSHI,0; MOVWF SSHI; MOVLW 0F0H; ANDWF SSHI; SWAPF SSHI; MOVLW 00H; IORWF SSHI; MOVF SSHI,0; MOVWF PORTC; CALL YANSHI; GOTO SHAOMIAO;循環掃描 ;
查中斷源 SERVE MOVWF WTEMP; SWAPF STATUS,W; CLRF STATUS; MOVWF STEMP;保護現場 MOVF PCLATH,W; MOVWF PCLATH_TEMP; CLRF PCLATH BTFSS INTCON,INTF;是INT中斷嗎? GOTO SERVE1;不是,轉SERVE1 GOTO INTT;是,轉INT中斷處理 SERVE1 BTFSS INTCON,T0IF;是定時期中斷嗎? GOTO SERVE2;不是,轉SERVE2 GOTO T0II;是,轉定時期中斷處理 SERVE2 BTFSS INTCON,RBIF;是RB中斷嗎? GOTO SERVE3;不是,返回 GOTO PDRB;是,轉RB中斷處理 SERVE3 RETFIE ;定時器中斷處理 T0II BCF INTCON,T0IF;清中斷標志位 BCF INTCON,T0IE;關定時期中斷 MOVF TEMP,0;重新值數 MOVWF TMR0; BCF INTCON,GIE;防止/原因是:產生中斷時,GIE位清0,并轉入中斷入口,當GIE清0后,如果這時正好CPU在執行 BSF INTCON,T0IE;產生/一條對INTCON“讀,修改,寫”的指令,則GIE位還會被寫會操作重新值1,這樣會使CPU BSF INTCON,GIE;兩次中斷/產生兩次中斷,解決的辦法就是,在對INTCON進行修改之前,事先值GIE=0,修改完后 DECFSZ COUNT,1;/再恢復GIE=1。 GOTO LOOP;返回 MOVLW D'20'; MOVWF COUNT;賦記數次數 INCF CMIAO,1;
MOVLW D'60'; XORWF CMIAO,W; BTFSS STATUS,Z; GOTO LOOP; CLRF CMIAO;60秒到清0 INCF CFEN; MOVLW D'60'; XORWF CFEN,W; BTFSS STATUS,Z; GOTO LOOP; CLRF CFEN;60分到清0 INCF CSHI; MOVLW D'24'; XORWF CSHI,W; BTFSS STATUS,Z; GOTO LOOP; CLRF CSHI;24時到清0 RETFIE;
;判斷是那一個產生的中斷 PDRB MOVF PORTB,0; MOVWF RBTEMP ; BTFSC RBTEMP,5;是0嗎?是轉向RBII GOTO RBIII;不是,轉向RBIII ;RB5口中斷處理 調秒 RBII CALL DELAY;去抖 BTFSC PORTB,5;是下降沿嗎? GOTO LOOP8;不是,轉(清除上升沿產生的虛假中斷) MOVF PORTB,1;讀PORTB,終結失陪條件 BCF INTCON,RBIF;清標志位 ; BCF INTCON,T0IF BCF INTCON,T0IE;關定時期中斷 MOVF TEMP,0; MOVWF TMR0;
重新賦值 BSF INTCON,T0IE;開定時期中斷 INCF CMIAO,1; MOVLW D'60'; XORWF CMIAO,W;判斷到60秒了嗎? BTFSS STATUS,Z; GOTO LOOP;返回 CLRF CMIAO; INCF CFEN,1; RETFIE LOOP8 MOVF PORTB,1;清除RBIF前要讀口 BCF INTCON,RBIF; RETFIE ;RB4口中斷處理 調分 RBIII CALL DELAY;去抖 BTFSC PORTB,4; GOTO LOOP8; MOVF PORTB,1; BCF INTCON,RBIF; BCF INTCON,T0IE; ; BCF INTCON,T0IF MOVF TEMP,W; MOVWF TMR0; BSF INTCON,T0IE; INCF CFEN,1; MOVLW D'60'; XORWF CFEN,W; BTFSS STATUS,Z; GOTO LOOP; CLRF CFEN; INCF CSHI; RETFIE ;外部中斷處理 調時 INTT BCF INTCON,INTF; CALL DELAY; INCF CSHI,1; MOVLW D'24'; XORWF CSHI,W; BTFSS STATUS,Z; GOTO LOOP; CLRF CSHI; RETFIE ;恢復現場 LOOP MOVF PCLATH_TEMP,W; MOVWF PCLATH; SWAPF STEMP,0; MOVWF STATUS; SWAPF WTEMP; SWAPF WTEMP,0; RETFIE ;去抖程序
延時8MS(5-10MS) DELAY MOVLW D'51'; MOVWF DY1; LOOP4 MOVLW D'51'; MOVWF DY2; LOOP5 DECFSZ DY2,1; GOTO LOOP5; DECFSZ DY1,1; GOTO LOOP4; RETURN ;延時程序,延時約3MS,(10-20MS循環一次,六個數碼官需要18MS,在次范圍內) YANSHI MOVLW D'21'; MOVWF DY5; LOOP7 MOVLW D'51'; MOVWF DY6; LOOP6 DECFSZ DY6,1; GOTO LOOP6; DECFSZ DY5,1; GOTO LOOP7; RETURN
BCD2 MOVLW 8; MOVWF COUNTER; ;循環左移計數器置8 CLRF BUFFER ; ;清除緩沖器 MOVF DIGHT,W ; MOVWF BUFFER1 ; LOOP2 RLF BUFFER1,1 ; ;二進制數轉換成BCD碼(以便顯示) RLF BUFFER,1; DECFSZ COUNTER,1; ;左移8次 GOTO ADJUST ; ; MOVF BUFFER,W; MOVWF DISPBUF ; MOVF DISPBUF,W; RETURN ;是否有進位(即已達100),如已計數到100則 ; SKPC ;從0開始再計數顯示(顯示00~99)
ADJUST MOVLW 3 ; ;二進制轉BCD的調整 ADDWF BUFFER,W; ;每次移位后都檢查低四位LSD+3是否大于7 MOVWF SUM ; BTFSC SUM,3; MOVWF BUFFER; MOVLW 30H; ADDWF BUFFER,W ; ;如果是則再加3,否則不加。 MOVWF SUM; BTFSC SUM,7; MOVWF BUFFER; ;接著再將高四位MSD作相同處理 GOTO LOOP2; END