#INCLUDE"P16F877.inc" W_TEMP EQU 20H ; 實際上20H、A0H、120H和1A0H STATUS_TEMP EQU 21H ;在體0中建立保護單元 PCLATH_TEMP EQU 22H ;在體0中建立保護單元 ORG 000H GOTO A1 ORG 004H;定時中斷入口地址 GOTO ZD01; ORG 0CH ;******************************************** ; 數據表 ;******************************************** Q1 ADDWF PCL,1 RETLW 00C0H ;0 RETLW 00F9H ;1 RETLW 00A4H ;2 RETLW 00B0H ;3 RETLW 0099H ;4 RETLW 0092H ;5 RETLW 0082H ;6 RETLW 00F8H ;7 RETLW 0080H ;8 RETLW 0090H ;9 RETLW 0088H ;A RETLW 0083H ;B RETLW 00C6H ;C RETLW 00A1H ;D RETLW 0086H ;E RETLW 008EH ;F A1 MOVLW 5;顯示位數 MOVWF 40H; MOVLW B'00000001';位碼 MOVWF 41H; MOVLW 5AH; MOVWF FSR ;間接尋址 BSF STATUS,RP0;選擇體1 BCF STATUS,RP1; MOVLW 00H;1:2TMRO比例 MOVWF OPTION_REG;分頻1/2 BCF STATUS,RP0;體0 BCF STATUS,RP1; MOVLW 0FFH; MOVFW TMR0;初值 BCF INTCON,T0IF;清定時中斷標志 BSF INTCON,T0IE;開定時中斷 BSF INTCON,GIE;開總中斷 A2 CALL ADC1 CALL CL0;將16進制數調整為5位10進制數 MOVFW 54H MOVWF 5AH MOVFW 53H MOVWF 5BH MOVFW 52H MOVWF 5CH MOVFW 51H MOVWF 5DH MOVFW 50H MOVWF 5EH CALL M001 GOTO A2 CL0 ; MOVLW 0H ;要顯示16進制數低位 ; MOVWF 50H; ; MOVLW 00H; ; MOVWF 51H;要顯示16進制數高位 CALL CL1 MOVLW B'00001111' ANDWF 54H,0 MOVWF 50H MOVLW B'11110000' ANDWF 54H,1 SWAPF 54H,0 MOVWF 51H MOVFW 52H MOVWF 54H MOVLW B'00001111' ANDWF 53H,0 MOVWF 52H MOVLW B'11110000' ANDWF 53H,1 SWAPF 53H,1 RETURN CL1 MOVLW 0; MOVWF 52H;萬位 MOVWF 53H;百千位 MOVWF 54H;個十位 MOVWF 55H;進位標志 MOVLW 10H; MOVWF 56H;循環次數 CLRF 57H; CL2 BCF STATUS,C;清C RLF 51H,1;循環左移 RLF 50H,1;循環左移 BTFSC STATUS,C;判斷C位是否為高 BSF 55H,0;是置1 MOVFW 54H; ADDWF 55H,0;PIC沒有ADDC指令只能判斷C來加1 ADDWF 54H,0;與自身相加 BTFSC STATUS,C;判斷是否有進位 BSF 57H,7;有則置標志 BTFSC STATUS,DC;判斷是否有進位 BSF 57H,3;有則置標志 CALL DA1;調用十進制調整子程序 MOVWF 54H;存回54H CLRF 55H;清進位標志 BTFSC STATUS,C;判斷C位是否為高 BSF 55H,0;是置1 MOVFW 53H; ADDWF 55H,0;PIC沒有ADDC指令只能判斷C來加1 ADDWF 53H,0;與自身相加 BTFSC STATUS,C; BSF 57H,6; BTFSC STATUS,DC;判斷是否有進位 BSF 57H,2;有則置標志 CALL DA1; MOVWF 53H; CLRF 55H ; BTFSC STATUS,C; BSF 55H,0; MOVFW 52H; ADDWF 55H,0; ADDWF 52H,0; BTFSC STATUS,C; BSF 57H,5; BTFSC STATUS,C;判斷是否有進位 BSF 57H,1;有則置標志 CALL DA1; MOVWF 52H; CLRF 55H; BTFSS 57H,7;判斷標志是否有進位 GOTO CL03;否 INCF 53H,1;是進位 MOVLW 60H; ADDWF 54H,1;自身加60H CL03 BTFSS 57H,3;判斷標志是否有進位 GOTO CL3;否 MOVLW 6H; ADDWF 54H,1;自身加6H CL3 BTFSS 57H,6;判斷標志是否有進位 GOTO CL04; INCF 52H,1;是進位 MOVLW 60H; ADDWF 53H,1;自身加60H CL04 BTFSS 57H,2;判斷標志是否有進位 GOTO CL4;否 MOVLW 6H; ADDWF 53H,1;自身加6H CL4 BTFSS 57H,5;判斷標志是否有進位 GOTO CL05; INCF 51H,1;是進位 MOVLW 60H; ADDWF 52H,1;自身加60H CL05 BTFSS 57H,1;判斷標志是否有進位 GOTO CL5;否 MOVLW 6H; ADDWF 52H,1;自身加6H CL5 CLRF 57H;清標志 DECFSZ 56H,1; GOTO CL2; RETURN; ;;;************************************************************** ;;; 十進制數調整 ;;;************************************************************** DA1 MOVWF 60H;將W里的數保存到60H里 MOVLW B'00001111'; ANDWF 60H,0;將60H的數與00001111去除高4位 MOVWF 62H;將去除高位后的數保存到62H MOVLW 0AH; SUBWF 62H,0;去除高位的數減0AH BTFSS STATUS,DC;判斷是否比0AH大 GOTO DA2 ;否則跳轉 ADDLW B'10000';比0AH大則進位 MOVWF 62H;高4位加1 DA2 MOVLW B'11110000'; ANDWF 60H,1;將60H的數與11110000去除低4位 MOVLW 0A0H; SUBWF 60H,0;高4位的數減0A0H BTFSS STATUS,C;判斷是否比0A0H大 GOTO DA3;否 ADDWF 62H,1;是則將差加上低位 BSF STATUS,C;是則置位 GOTO DA4; DA3 MOVFW 60H; ADDWF 62H,1;否則將高4位加上低4位 MOVFW 62H; ANDLW B'11110000'; SUBLW 0A0H ;加后判斷是否大于或等于0A0H BCF STATUS,C; BTFSS STATUS,Z; GOTO DA4;否則退出 MOVLW B'00001111';是 ANDWF 62H,1;則去掉高4位并進位 BSF STATUS,C;置進位標志 DA4 MOVFW 62H; RETURN; ;************************************************************** ; 定時中斷數碼管顯示程序 ;************************************************************** ZD01 BTFSS INTCON,T0IF;判斷是否產生定時中斷 GOTO ZD03;否跳出是繼續執行 MOVWF W_TEMP;W備份到W_TEMP中 SWAPF STATUS,0;STATUS半字交換后送W CLRF STATUS;選擇體0為當前體備份 MOVWF STATUS_TEMP;將原來的STATUS送體0上的 MOVF PCLATH,0;PCLATH送W MOVWF PCLATH_TEMP;W送備份寄存器中 CLRF PCLATH ;設置為0頁 BCF INTCON,T0IF BSF STATUS,RP0;體1 BCF STATUS,RP1; MOVLW 0; MOVWF TRISB;RB口設為輸出口 MOVWF TRISD;RD口設為輸出口 BCF STATUS,RP0;體0 BCF STATUS,RP1; MOVLW 0FFH; MOVWF PORTB;RB口輸出高電平 MOVLW 0 MOVWF PORTD;RD口輸出低電平起清屏作用 MOVFW INDF;間接尋址顯示數據 CALL Q1;查數據表 MOVWF PORTB;顯示斷碼輸出到RB口 INCF FSR,1;間接尋址地址加1 MOVFW 41H ;位碼 MOVWF PORTD;位碼輸出到RD口 RLF 41H,0;處理C RLF 41H,1;左移位碼 DECFSZ 40H,1;判斷是否顯示完4位 GOTO ZD02;否則繼續顯示 MOVLW 5;顯示位數 MOVWF 40H; MOVLW B'00000001';位碼 MOVWF 41H; MOVLW 5AH; MOVWF FSR ;間接尋址 ZD02 MOVLW 0FFH; MOVFW TMR0;重裝初值 ; 恢復現場 CLRF STATUS;恢復到體0 MOVF PCLATH_TEMP,0;開始恢復數據 MOVWF PCLATH;恢復PCLATH SWAPF STATUS_TEMP,0 MOVWF STATUS;恢復STATUS SWAPF W_TEMP,1;半字交換后放回 SWAPF W_TEMP,0;再半字交換后送W ZD03 RETFIE ;中斷返回 ADC1 BSF STATUS,RP0;體1 BCF STATUS,RP1 MOVLW 0FFH MOVWF TRISA;設置A口為輸入口 MOVLW B'10001110';設置ADC轉換格式為右對齊并選RA0位AD口 MOVWF ADCON1 BCF STATUS,RP0;選擇體0 BCF STATUS,RP1 MOVLW B'11000001' ;選擇ADC時鐘頻率選擇RA0位AD通道使能ADC MOVWF ADCON0 BSF ADCON0,GO;開始AD轉換 BTFSC ADCON0,GO;判斷是否轉換完成 GOTO $-1 BSF ADCON0,GO;清完成標志 MOVFW ADRESH;將轉換完成高位數存到50H MOVWF 50H BSF STATUS,RP0;體1 BCF STATUS,RP1 MOVFW ADRESL;將轉換完成數存到51H BCF STATUS,RP0;體0 BCF STATUS,RP1 MOVWF 51H RETURN M001 MOVLW 1 MOVWF 30H M002 MOVLW D'24' MOVWF 31H M003 MOVLW D'250' MOVWF 32H DECFSZ 32H,1 GOTO $-1 DECFSZ 31H,1 GOTO M003 DECFSZ 30H,1 GOTO M002 RETURN END