list p=16f77,r=HEX include"p16f77.inc" __CONFIG _XT_OSC&_WDT_OFF&_BODEN_OFF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CBLOCK 0x20 DLY1 DLY2 DLY3 CNT PTR TMP SEC MIN HUR VALUE ADDRESS RTC_VALUE CMD YEAR MON DATE STUT BCD_TMP NUM_FLAG ENDC IRQ SET 7 ;for portD DS SET 6 RW SET 5 AS SET 4 CS SET 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ORG 0x0000 CALL INITIAL CALL RTC_INIT GOTO MAIN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INITIAL: BANKSEL TRISA MOVLW 0x00 ;PORTA=OUTPUT MOVWF TRISA ;七段顯示器驅動電晶體 MOVLW 0x00 ;PORTC=OUTPUT MOVWF TRISD ;七段顯示器數值顯示 MOVLW 0x87 ;IRQ DS RW AS CS S1 S2 S3 MOVWF TRISD ; 1 0 0 0 0 1 1 1 BANKSEL PORTA MOVLW 0x00 ;禁能DS12C887讀取寫入 MOVWF PORTD MOVLW 0xFF MOVWF PORTA BSF STUT,0 RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RTC_INIT: BANKSEL PORTA MOVLW 0x0A ;設定RTC 0x0A暫存器 MOVWF ADDRESS MOVLW B'00101001' ;啟動震盪並計時,輸出方波4Hz MOVWF CMD CALL RTC_WRITE MOVLW 0x0B ;設定RTC 0x0B暫存器 MOVWF ADDRESS MOVLW B'00011010' ;致能產生時間改變中斷信號,DM=BCD CODE MOVWF CMD CALL RTC_WRITE MOVLW 0x08 MOVWF PORTD RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN: MOVLW 0x16 ;50 MOVWF DLY3 CALL DELAY ;延遲0.5秒 BTFSS PORTD,1 GOTO START MOVLW 0xFA ;250 MOVWF DLY3 CALL DELAY ;延遲5秒 BTFSS PORTD,1 ;檢查是否確認按鈕 GOTO START ;否,離開 CALL DEFAULT_RTC GOTO START_ACTIVE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; START: BTFSS PORTD,1 GOTO START MOVLW 0x32 MOVWF DLY3 CALL DELAY CALL RTC_INIT GOTO START_ACTIVE START_CLOSE: MOVLW 0xFF MOVWF PORTA MOVLW 0x16 MOVWF DLY3 CALL DELAY MOVLW 0x0B ;設定RTC 0x0B暫存器 MOVWF ADDRESS MOVLW B'00001010' ;致能產生時間改變中斷信號,DM=BCD CODE MOVWF CMD CALL RTC_WRITE GOTO START START_ACTIVE: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;檢查RTC是否更新資料是否關閉顯示 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BTFSC PORTD,1 GOTO START_CLOSE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;檢查RTC是否更新資料 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BTFSS PORTD,IRQ CALL GET_RTC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;檢查時間設定時間鈕是否被按下 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BTFSC PORTD,2 CALL SET_RTC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;時間/日期 顯示 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BTFSC STUT,0 ;STUT,0=1的時候顯示時間 CALL DISPLAY_TIME BTFSC STUT,0 GOTO START_ACTIVE CALL DISPLAY_DATE;STUT,0=0的時候顯示日期 GOTO START_ACTIVE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BCD_NUM: addwf PCL DT 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x03,0x03,0x03 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;顯示時間 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAY_TIME: BANKSEL PORTB MOVF SEC,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00011111' MOVWF PORTA CALL DELAY2 SWAPF SEC,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00101111' MOVWF PORTA CALL DELAY2 MOVF MIN,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00110111' MOVWF PORTA CALL DELAY2 SWAPF MIN,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111011' MOVWF PORTA CALL DELAY2 MOVF HUR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111101' MOVWF PORTA CALL DELAY2 SWAPF HUR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111110' MOVWF PORTA CALL DELAY2 BTFSS PORTD,0 RETURN BTFSC PORTD,0 BCF STUT,0 MOVLW 0xFF MOVWF PORTA MOVLW 0x19 MOVWF DLY3 CALL DELAY RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;顯示日期 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAY_DATE: BANKSEL PORTB MOVF DATE,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00011111' MOVWF PORTA CALL DELAY2 SWAPF DATE,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00101111' MOVWF PORTA CALL DELAY2 MOVF MON,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00110111' MOVWF PORTA CALL DELAY2 SWAPF MON,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111011' MOVWF PORTA CALL DELAY2 MOVF YEAR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111101' MOVWF PORTA CALL DELAY2 SWAPF YEAR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111110' MOVWF PORTA CALL DELAY2 BTFSS PORTD,0 RETURN BTFSC PORTD,0 BSF STUT,0 MOVLW 0xFF MOVWF PORTA MOVLW 0x19 MOVWF DLY3 CALL DELAY RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;設定RTC初始時間 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEFAULT_RTC: MOVLW 0x0B ;將RTC_SET設定為1 MOVWF ADDRESS ;設定時間 MOVLW B'10011010' MOVWF CMD CALL RTC_WRITE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;時間設定 00:00:00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVLW 0x00 ;設定秒 MOVWF ADDRESS MOVLW 0x00 MOVWF CMD CALL RTC_WRITE MOVLW 0x02 ;設定分 MOVWF ADDRESS MOVLW 0x00 MOVWF CMD CALL RTC_WRITE MOVLW 0x04 ;設定時 MOVWF ADDRESS MOVLW 0x00 MOVWF CMD CALL RTC_WRITE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;日期設定 08/01/01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVLW 0x07 ;設定日 MOVWF ADDRESS MOVLW 0x01 MOVWF CMD CALL RTC_WRITE MOVLW 0x08 ;設定月 MOVWF ADDRESS MOVLW 0x01 MOVWF CMD CALL RTC_WRITE MOVLW 0x09 ;設定年 MOVWF ADDRESS MOVLW 0x10 MOVWF CMD CALL 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 PORTC MOVLW 0x32 MOVWF DLY3 CALL DELAY RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SET_RTC: MOVLW 0x00 MOVWF PORTA MOVLW B'10110110' MOVWF PORTC MOVLW 0x96 ;150 MOVWF DLY3 CALL DELAY BTFSS PORTD,2 RETURN ;按鈕彈跳?離開設定程序 GOTO HUR_SET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;開始設定時間 時間>日期 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HUR_SET: MOVF HUR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111101' MOVWF PORTA CALL DELAY2 SWAPF HUR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111110' MOVWF PORTA CALL DELAY2 BTFSC PORTD,1 GOTO MIN_SET2 BTFSS PORTD,0 GOTO HUR_SET MOVF HUR,W MOVWF BCD_TMP MOVLW B'00100100' ;24 MOVWF NUM_FLAG CALL LBYTE_ADD ;設定時間 MOVF BCD_TMP,W MOVWF HUR GOTO HUR_SET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MIN_SET2: MOVLW 0xFF MOVWF PORTA MOVLW 0x19 MOVWF DLY3 CALL DELAY MIN_SET: MOVF MIN,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00110111' MOVWF PORTA CALL DELAY2 SWAPF MIN,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111011' MOVWF PORTA CALL DELAY2 BTFSC PORTD,1 GOTO SEC_SET2 BTFSS PORTD,0 GOTO MIN_SET MOVF MIN,W MOVWF BCD_TMP MOVLW B'01100000' ;60 MOVWF NUM_FLAG CALL LBYTE_ADD ;設定時間 MOVF BCD_TMP,W MOVWF MIN GOTO MIN_SET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SEC_SET2: MOVLW 0xFF MOVWF PORTA MOVLW 0x19 MOVWF DLY3 CALL DELAY SEC_SET: MOVF SEC,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00011111' MOVWF PORTA CALL DELAY2 SWAPF SEC,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00101111' MOVWF PORTA CALL DELAY2 BTFSC PORTD,1 GOTO SAVE_TIME BTFSS PORTD,0 GOTO SEC_SET MOVF SEC,W MOVWF BCD_TMP MOVLW B'01100000' ;60 MOVWF NUM_FLAG CALL LBYTE_ADD ;設定時間 MOVF BCD_TMP,W MOVWF SEC GOTO SEC_SET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; YEAR_SET2: MOVLW 0xFF MOVWF PORTA MOVLW 0x19 MOVWF DLY3 CALL DELAY YEAR_SET: MOVF YEAR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111101' MOVWF PORTA CALL DELAY2 SWAPF YEAR,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111110' MOVWF PORTA BTFSC PORTD,1 GOTO MON_SET2 BTFSS PORTD,0 GOTO YEAR_SET MOVF YEAR,W MOVWF BCD_TMP MOVLW B'10011001' ;99 MOVWF NUM_FLAG CALL LBYTE_ADD ;設定時間 MOVF BCD_TMP,W MOVWF YEAR GOTO YEAR_SET MON_SET2: MOVLW 0xFF MOVWF PORTA MOVLW 0x19 MOVWF DLY3 CALL DELAY MON_SET: MOVF MON,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00110111' MOVWF PORTA CALL DELAY2 SWAPF MON,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00111011' MOVWF PORTA CALL DELAY2 BTFSC PORTD,1 GOTO DATE_SET2 BTFSS PORTD,0 GOTO MON_SET MOVF MON,W MOVWF BCD_TMP MOVLW B'00010011' ;13 MOVWF NUM_FLAG CALL LBYTE_ADD ;設定時間 MOVF BCD_TMP,W MOVWF MON GOTO MON_SET DATE_SET2: MOVLW 0xFF MOVWF PORTA MOVLW 0x19 MOVWF DLY3 CALL DELAY DATE_SET: MOVF DATE,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00011111' MOVWF PORTA CALL DELAY2 SWAPF DATE,W ANDLW 0x0F CALL BCD_NUM MOVWF PORTC MOVLW B'00101111' MOVWF PORTA CALL DELAY2 BTFSC PORTD,1 GOTO SAVE_DATE BTFSS PORTD,0 GOTO DATE_SET MOVF DATE,W MOVWF BCD_TMP MOVLW B'00110010' ;32 MOVWF NUM_FLAG CALL LBYTE_ADD ;設定時間 MOVF BCD_TMP,W MOVWF DATE GOTO DATE_SET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LBYTE_ADD: MOVLW 0x03 MOVWF DLY3 CALL DELAY BTFSS PORTD,0 RETURN BCF STATUS,Z MOVF BCD_TMP,W ANDLW B'00001111' ;檢查LOW BYTE是否等於9 SUBLW B'00001001' BTFSC STATUS,Z ;檢查Z是否等於0 GOTO HBYTE_ADD ;Z=0,已到9 INCF BCD_TMP,F MOVF BCD_TMP,W BCF STATUS,Z SUBWF NUM_FLAG,W ;檢查是否達盡頭 BTFSC STATUS,Z GOTO RESET_00 MOVLW 0x0F MOVWF DLY3 CALL DELAY RETURN HBYTE_ADD: MOVF BCD_TMP,W ADDLW B'00010000' ;將HI BYTE+1 ANDLW B'11110000' ;將LOW BYTE清除 MOVWF BCD_TMP SUBWF NUM_FLAG,W ;檢查是否達盡頭 BTFSC STATUS,Z GOTO RESET_00 MOVLW 0x0F MOVWF DLY3 CALL DELAY RETURN RESET_00: CLRF BCD_TMP MOVF BCD_TMP,W MOVWF BCD_TMP MOVLW 0x0F MOVWF DLY3 CALL DELAY RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SAVE_TIME: MOVLW 0x0B ;將RTC_SET設定為1 MOVWF ADDRESS ;設定時間 MOVLW B'10011010' MOVWF CMD CALL RTC_WRITE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;時間設定 00:00:00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVLW 0x00 ;設定秒 MOVWF ADDRESS MOVF SEC,W MOVWF CMD CALL RTC_WRITE MOVLW 0x02 ;設定分 MOVWF ADDRESS MOVF MIN,W MOVWF CMD CALL RTC_WRITE MOVLW 0x04 ;設定時 MOVWF ADDRESS MOVF HUR,W MOVWF CMD CALL RTC_WRITE MOVLW 0x0B ;將RTC_SET設定為1 MOVWF ADDRESS ;設定時間 MOVLW B'00011010' MOVWF CMD CALL RTC_WRITE MOVLW 0xFF MOVWF PORTA MOVLW 0x32 MOVWF DLY3 CALL DELAY GOTO YEAR_SET2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SAVE_DATE: MOVLW 0x0B ;將RTC_SET設定為1 MOVWF ADDRESS ;設定時間 MOVLW B'10011010' MOVWF CMD CALL RTC_WRITE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;日期設定 00/00/00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVLW 0x07 ;設定日 MOVWF ADDRESS MOVF DATE,W MOVWF CMD CALL RTC_WRITE MOVLW 0x08 ;設定月 MOVWF ADDRESS MOVF MON,W MOVWF CMD CALL RTC_WRITE MOVLW 0x09 ;設定年 MOVWF ADDRESS MOVF YEAR,W MOVWF CMD CALL RTC_WRITE MOVLW 0x0B ;將RTC_SET設定為1 MOVWF ADDRESS ;設定時間 MOVLW B'00011010' MOVWF CMD CALL RTC_WRITE MOVLW 0xFF MOVWF PORTA MOVLW 0x32 MOVWF DLY3 CALL DELAY GOTO START_ACTIVE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GET_RTC: MOVLW 0x00 ;讀秒 MOVWF ADDRESS CALL RTC_READ MOVF RTC_VALUE,W MOVWF SEC MOVLW 0x02 ;讀分 MOVWF ADDRESS CALL RTC_READ MOVF RTC_VALUE,W MOVWF MIN MOVLW 0x04 ;讀時 MOVWF ADDRESS CALL RTC_READ MOVF RTC_VALUE,W MOVWF HUR ;;;;讀取日期;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVLW 0x07 ;讀日 MOVWF ADDRESS CALL RTC_READ MOVF RTC_VALUE,W MOVWF DATE MOVLW 0x08 ;讀月 MOVWF ADDRESS CALL RTC_READ MOVF RTC_VALUE,W MOVWF MON MOVLW 0x09 ;讀年 MOVWF ADDRESS CALL RTC_READ MOVF RTC_VALUE,W MOVWF YEAR MOVLW 0x0C ;讀取中斷暫存器 MOVWF ADDRESS CALL RTC_READ RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;DS12C887命令寫入 RW ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RTC_WRITE: BANKSEL TRISB MOVLW 0x00 ;PORTB=OUTPUT MOVWF TRISB ;資料傳出 BANKSEL PORTD BSF PORTD,DS BSF PORTD,RW BSF PORTD,AS BCF PORTD,CS MOVF ADDRESS,W ;寫入位址 MOVWF PORTB BCF PORTD,AS BCF PORTD,RW ;寫入資料 MOVF CMD,W MOVWF PORTB BSF PORTD,RW MOVLW 0x08 ;禁能DS12C887 MOVWF PORTD RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;DS12C887資料讀出 DS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RTC_READ: BANKSEL TRISB MOVLW 0x00 ;PORTB=OUTPUT MOVWF TRISB ;資料傳出 BANKSEL PORTD BSF PORTD,DS BSF PORTD,RW BSF PORTD,AS BCF PORTD,CS MOVF ADDRESS,W ;寫入位址 MOVWF PORTB BCF PORTD,AS BANKSEL TRISB MOVLW 0xFF ;PORTB=INPUT MOVWF TRISB ;資料寫入 BANKSEL PORTD BCF PORTD,DS ;讀出資料 NOP MOVF PORTB,W MOVWF RTC_VALUE BSF PORTD,DS MOVLW 0x08 ;禁能DS12C887 MOVWF PORTD RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;CALL DELAY TIMES=20ms*DEY3 ;OSC:4MHz ;1MC≒(1/(4000000/4))≒0.000001≒1us ; is 50=B'00110010' ≒ 1s ; is 25=B'00011001' ≒ 0.5s ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DELAY: MOVLW D'250' MOVWF DLY2 INNER2: MOVLW D'25' MOVWF DLY1 INNER1: DECFSZ DLY1,1 GOTO INNER1 DECFSZ DLY2,1 GOTO INNER2 DECFSZ DLY3,1 GOTO DELAY RETURN DELAY2: MOVLW D'1' MOVWF DLY2 INNER2_2: MOVLW D'150' MOVWF DLY1 INNER1_2: DECFSZ DLY1,1 GOTO INNER1_2 DECFSZ DLY2,1 GOTO INNER2_2 RETURN END