#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 [page]
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