
這是個配合RTC DS12C887做出來的時鐘功能
大致上已經有基本的所有功能 時間與日期的顯示修改
這個程序的功能有還原預設值 00:00:00 與 (20)10/01/01
以及時間 時分秒 加減設定 儲存設定 取消設定
日期設定同時間設定
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SET_RTC: BANKSEL PORTA MOVLW 0x00 MOVWF PORTA MOVLW B'10110110' MOVWF PORTD MOVLW 0x96 ;3秒 MOVWF DLY3 CALL DELAY BTFSS SW4 RETURN GOTO SET_DISPLAY SET_DISPLAY: BANKSEL PORTA BSF TIME_DATE_FLAG,1 ;宣告進入設定模式 MOVLW 0xAA ;將顯示狀態清除為空 MOVWF SEG0 MOVWF SEG1 MOVWF SEG2 CALL DISPLAY BTFSC SW6 ;檢查是否按下SW6 CALL DEFAULT_RTC ;呼叫檢查是否還原預設值副程式 BTFSC SW4 ;檢查是否放開按鍵 GOTO SET_DISPLAY BTFSS TIME_DATE_FLAG,0 GOTO TIME_SET ;TIME_DATE_FLAG,1 = 0 進入時間設定 GOTO DATE_SET ;TIME_DATE_FLAG,1 = 1 進入日期設定 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TIME_SET: ;進入TIME SET設定切換順序 時>分>秒 ;各按鍵說明 SW4:VALUE+1 ; SW5:VALUE-1 ; SW6:短按,切換 長按離開 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TIME_SET_HUR: MOVLW 0xAA MOVWF SEG1 MOVWF SEG0 MOVF HUR,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG2 CALL DISPLAY BTFSC SW5 GOTO CANCEL_RESET BTFSC SW4 GOTO SAVE_TIME BTFSC SW6 GOTO TIME_SET_HUR SET_HUR: BANKSEL PORTA CALL DISPLAY ;CALL DISPLAY TIME FUNCTION MOVF HUR,W ;SEG0=HUR,SEG1=AA,SEG2=AA MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG2 ;hi byte BTFSC SW4 ;IF PRESS KEY SW4 GO ADD HUR (HUR+1) CALL ADD_VALUE BTFSC SW5 ;IF PRESS KEY SW5 GO CUT HUR (HUR-1) CALL CUT_VALUE BTFSC SW6 ;檢查是否按下切換鈕 GOTO TIME_SET_MIN MOVF SET_TMP,W MOVWF HUR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Check HUR HI BYTE IS NOT OVER 23 OR 00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HUR_FF COMF HUR,W BTFSS STATUS,Z GOTO HUR_20 ;NOT ZERO,GOTO CHECK OVER_0A MOVLW 0x23 MOVWF HUR HUR_20: SWAPF HUR,W ANDLW 0x0F ;CHECK 02 SUBLW 0x02 BTFSC STATUS,Z GOTO HUR_04 ;IS OVER 20 GOTO SET_HUR ;NOT OVER 20 HUR_04: MOVF HUR,W ANDLW 0x0F ;CHECK 03 SUBLW 0x04 BTFSS STATUS,Z GOTO SET_HUR ;NOT OVER 23 CLRF HUR ;IS OVER 23 CLEAR HUR GOTO SET_HUR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TIME_SET_MIN: MOVLW 0xAA MOVWF SEG2 MOVLW SEG0 MOVF MIN,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG1 CALL DISPLAY BTFSC SW5 GOTO CANCEL_RESET BTFSC SW4 GOTO SAVE_TIME BTFSC SW6 GOTO TIME_SET_MIN SET_MIN: MOVF MIN,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG1 CALL DISPLAY BTFSC SW6 GOTO TIME_SET_SEC BTFSC SW4 ;IF PRESS KEY SW4 GO ADD HUR (HUR+1) CALL ADD_VALUE BTFSC SW5 ;IF PRESS KEY SW5 GO CUT HUR (HUR-1) CALL CUT_VALUE MOVF SET_TMP,W MOVWF MIN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Check HUR HI BYTE IS NOT OVER 23 OR 00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MIN_FF COMF MIN,W BTFSS STATUS,Z GOTO MIN_20 ;NOT ZERO,GOTO CHECK OVER_0A MOVLW 0x59 MOVWF MIN MIN_20: SWAPF MIN,W ANDLW 0x0F ;CHECK 02 SUBLW 0x06 BTFSC STATUS,Z GOTO MIN_04 ;IS OVER 20 GOTO SET_MIN ;NOT OVER 20 MIN_04: MOVF MIN,W ANDLW 0x0F ;CHECK 03 SUBLW 0x00 BTFSS STATUS,Z GOTO SET_MIN ;NOT OVER 23 CLRF MIN ;IS OVER 23 CLEAR HUR GOTO SET_MIN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TIME_SET_SEC: MOVLW 0xAA MOVWF SEG2 MOVWF SEG1 MOVF SEC,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG0 CALL DISPLAY BTFSC SW5 GOTO CANCEL_RESET BTFSC SW4 GOTO SAVE_TIME BTFSC SW6 GOTO TIME_SET_SEC SET_SEC: MOVF SEC,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG0 CALL DISPLAY BTFSC SW6 GOTO TIME_SET_HUR BTFSC SW4 ;IF PRESS KEY SW4 GO ADD HUR (HUR+1) CALL ADD_VALUE BTFSC SW5 ;IF PRESS KEY SW5 GO CUT HUR (HUR-1) CALL CUT_VALUE MOVF SET_TMP,W MOVWF SEC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Check HUR HI BYTE IS NOT OVER 23 OR 00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SEC_FF COMF SEC,W BTFSS STATUS,Z GOTO SEC_20 ;NOT ZERO,GOTO CHECK OVER_0A MOVLW 0x59 MOVWF SEC SEC_20: SWAPF SEC,W ANDLW 0x0F ;CHECK 02 SUBLW 0x06 BTFSC STATUS,Z GOTO SEC_04 ;IS OVER 20 GOTO SET_SEC ;NOT OVER 20 SEC_04: MOVF SEC,W ANDLW 0x0F ;CHECK 03 SUBLW 0x00 BTFSS STATUS,Z GOTO SET_SEC ;NOT OVER 23 CLRF SEC ;IS OVER 23 CLEAR HUR GOTO SET_SEC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATE_SET: ;進入TIME SET設定切換順序 時>分>秒 ;各按鍵說明 SW4:VALUE+1 ; SW5:VALUE-1 ; SW6:短按,切換 長按離開 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATE_SET_YEAR: MOVLW 0xAA MOVWF SEG1 MOVWF SEG0 MOVF YEAR,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG2 CALL DISPLAY BTFSC SW5 GOTO CANCEL_RESET BTFSC SW4 GOTO SAVE_DATE BTFSC SW6 GOTO DATE_SET_YEAR SET_YEAR: BANKSEL PORTA CALL DISPLAY ;CALL DISPLAY TIME FUNCTION MOVF YEAR,W ;SEG0=HUR,SEG1=AA,SEG2=AA MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG2 ;hi byte BTFSC SW4 ;IF PRESS KEY SW4 GO ADD HUR (HUR+1) CALL ADD_VALUE BTFSC SW5 ;IF PRESS KEY SW5 GO CUT HUR (HUR-1) CALL CUT_VALUE BTFSC SW6 ;檢查是否按下切換鈕 GOTO DATE_SET_MON MOVF SET_TMP,W MOVWF YEAR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Check HUR HI BYTE IS NOT OVER 23 OR 00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; YEAR_FF COMF YEAR,W BTFSS STATUS,Z GOTO YEAR_20 ;NOT ZERO,GOTO CHECK OVER_0A MOVLW 0x98 MOVWF YEAR YEAR_20: SWAPF YEAR,W ANDLW 0x0F ;CHECK 09 SUBLW 0x09 BTFSC STATUS,Z GOTO YEAR_04 ;IS OVER 98 GOTO SET_YEAR ;NOT OVER 98 YEAR_04: MOVF YEAR,W ANDLW 0x0F ;CHECK 09 SUBLW 0x09 BTFSS STATUS,Z GOTO SET_YEAR ;NOT OVER 98 CLRF YEAR ;IS OVER 98 CLEAR YEAR GOTO SET_YEAR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATE_SET_MON: MOVLW 0xAA MOVWF SEG2 MOVLW SEG0 MOVF MON,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG1 CALL DISPLAY BTFSC SW5 GOTO CANCEL_RESET BTFSC SW4 GOTO SAVE_DATE BTFSC SW6 GOTO DATE_SET_MON SET_MON: MOVF MON,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG1 CALL DISPLAY BTFSC SW6 GOTO DATE_SET_DATE BTFSC SW4 ;IF PRESS KEY SW4 GO ADD HUR (HUR+1) CALL ADD_VALUE BTFSC SW5 ;IF PRESS KEY SW5 GO CUT HUR (HUR-1) CALL CUT_VALUE MOVF SET_TMP,W MOVWF MON ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Check HUR HI BYTE IS NOT OVER 23 OR 01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MON_FF MOVF MON,F BTFSS STATUS,Z GOTO MON_20 ;NOT ZERO,GOTO CHECK OVER_0A MOVLW 0x12 MOVWF MON MON_20: SWAPF MON,W ANDLW 0x0F ;CHECK 01 SUBLW 0x01 BTFSC STATUS,Z GOTO MON_04 ;IS OVER 12 GOTO SET_MON ;NOT OVER 20 MON_04: MOVF MON,W ANDLW 0x0F ;CHECK 03 SUBLW 0x03 BTFSS STATUS,Z GOTO SET_MON ;NOT OVER 12 MOVLW 0x01 MOVWF MON ;CLRF MON ;IS OVER 12 CLEAR HUR GOTO SET_MON ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATE_SET_DATE: MOVLW 0xAA MOVWF SEG2 MOVWF SEG1 MOVF DATE,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG0 CALL DISPLAY BTFSC SW5 GOTO CANCEL_RESET BTFSC SW4 GOTO SAVE_DATE BTFSC SW6 GOTO DATE_SET_DATE SET_DATE: MOVF DATE,W MOVWF SET_TMP ;USER OF SUBROUTINE MOVWF SEG0 CALL DISPLAY BTFSC SW6 GOTO DATE_SET_YEAR BTFSC SW4 ;IF PRESS KEY SW4 GO ADD HUR (HUR+1) CALL ADD_VALUE BTFSC SW5 ;IF PRESS KEY SW5 GO CUT HUR (HUR-1) CALL CUT_VALUE MOVF SET_TMP,W MOVWF DATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Check HUR HI BYTE IS NOT OVER 23 OR 00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATE_FF MOVF DATE,F BTFSS STATUS,Z GOTO DATE_20 ;NOT ZERO,GOTO CHECK OVER_0A MOVLW 0x31 MOVWF DATE DATE_20: SWAPF DATE,W ANDLW 0x0F ;CHECK 03 SUBLW 0x03 BTFSC STATUS,Z GOTO DATE_04 ;IS OVER 31 GOTO SET_DATE ;NOT OVER 31 DATE_04: MOVF DATE,W ANDLW 0x0F ;CHECK 02 SUBLW 0x02 BTFSS STATUS,Z GOTO SET_DATE ;NOT OVER 31 MOVLW 0x01 MOVWF DATE ;CLRF DATE ;IS OVER 31 CLEAR HUR GOTO SET_DATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADD_VALUE: CALL DISPLAY BTFSC SW4 GOTO ADD_VALUE BANKSEL SET_TMP INCF SET_TMP ;SET_TMP VALUE + 1 MOVF SET_TMP,W ANDLW 0x0F SUBLW 0x0A BTFSS STATUS,Z RETURN MOVLW 0xF0 ANDWF SET_TMP MOVLW 0x10 ADDWF SET_TMP RETURN CUT_VALUE: CALL DISPLAY BTFSC SW5 GOTO CUT_VALUE MOVF SET_TMP,F BTFSS STATUS,Z GOTO NO_00 MOVLW 0xFF MOVWF SET_TMP RETURN NO_00: BANKSEL SET_TMP DECF SET_TMP ;SET_TMP VALUE - 1 MOVF SET_TMP,W ANDLW 0x0F SUBLW 0x0F BTFSS STATUS,Z RETURN ;未溢位,返回程式 MOVLW 0xF9 ANDWF SET_TMP RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;設定RTC初始時間 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEFAULT_RTC: BTFSS SW5 ;檢查SW是否按下 RETURN ;未按下,狀態不成立 MOVLW 0xFA ;CALL DELAY 5s MOVWF DLY3 CALL DELAY BTFSS SW5 ;檢查SW5是否放開 RETURN ;SW5放開,返回時間設定模式 SET_DEFAULT: ;未放開,進入初始值設定模式 BANKSEL CMD PAGESEL RTC_WRITE MOVLW 0x0B ;將RTC_SET設定為1 MOVWF ADDRESS ;設定時間 MOVLW B'10011010' MOVWF CMD CALL RTC_WRITE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;時間設定 00:00:00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PAGESEL RTC_WRITE MOVLW 0x00 ;設定秒 MOVWF ADDRESS MOVLW 0x00 MOVWF CMD CALL RTC_WRITE PAGESEL RTC_WRITE MOVLW 0x02 ;設定分 MOVWF ADDRESS MOVLW 0x00 MOVWF CMD CALL RTC_WRITE PAGESEL RTC_WRITE MOVLW 0x04 ;設定時 MOVWF ADDRESS MOVLW 0x00 MOVWF CMD CALL RTC_WRITE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;日期設定 10/01/01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PAGESEL RTC_WRITE MOVLW 0x07 ;設定日 MOVWF ADDRESS MOVLW 0x01 MOVWF CMD CALL RTC_WRITE PAGESEL RTC_WRITE MOVLW 0x08 ;設定月 MOVWF ADDRESS MOVLW 0x01 MOVWF CMD CALL RTC_WRITE PAGESEL RTC_WRITE MOVLW 0x09 ;設定年 MOVWF ADDRESS MOVLW 0x10 MOVWF CMD CALL RTC_WRITE PAGESEL RTC_WRITE MOVLW 0x0B ;恢復RTC_數據更新將RTC_SET設定為0 MOVWF ADDRESS ;設定時間 MOVLW B'00011010' MOVWF CMD CALL RTC_WRITE MOVLW 0x00 MOVWF PORTA MOVLW B'11110111' MOVWF PORTD MOVLW 0x32 MOVWF DLY3 PAGESEL DELAY CALL DELAY PAGESEL MAIN GOTO MAIN ;初始化完畢,返回主程式 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;