基于Pic16f873的数字温度计及其源程序
list p=16f877 ;
include;
cnt equ 023h ;
sou equ 024h ;
souh equ 025h ;
rlt equ 026h ;
rlth equ 027h ;
temp1 equ 028h ;
temp2 equ 029h ;
temp3 equ 02ah ;
soub equ 02bh ;
souhb equ 02ch ;
;***********复位向量*************
org 0000h ;
nop ;
;*************主程序***************
main
;*****************初始化***********************
bsf status,rp0 ;选RAM体1
movlw b’10001110’ ;结果右对齐
movwf adcon1 ;AN0作为模拟信号输入口,参考电压为vdd,vss
movlw b’11010110’ ;设置RC口状态
movwf trisc ;只要SDI脚为输入
clrf sspstat ;主要清除SMP和CKE位
bcf status,rp0 ; 选RAM体0
movlw 01000001b ;
movwf adcon0 ;设置时钟源8tosc,使能adc,an0信道被选中
bcf pir1,adif ;
movlw b’00110010’ ;设置控制寄存器:设置fosc/64
movwf sspcon ;SPI主控方式;CKP=1
;******************** A/D转换********************
;入口参数:模拟信号加在RA0/AN0上。
;出口参数:10位转换结果在右对齐的souh:sou中。
start bsf adcon0,go ;开启A/D转换
btfsc adcon0,go ;A/D转换完成了吗?
goto $-1 ;未完,等待
movf adresh,w ;
movwf souh ;结果高位
bsf status,rp0 ;
movf adresl,w ;
bcf status,rp0 ;
movwf sou ;
;********判断sou:souh是否大于1000,即是否大于100℃?****
;入口参数:被减数在souhb:soub中,减数在rlth:rlt中。
;出口参数:结果在souhb:soub中,借位标志在STATUS:C中,'0'表示有借位。
movf sou,w ;
movwf soub ;
movf souh,w ;
movwf souhb ;
movlw 0e7h ;
movwf rlt ;
movlw 03h ;
movwf rlth ;
dusub movf rlt,w ;
subwf soub ;
movf rlth,w ;
btfss status,c ;
incfsz rlth,w ;
subwf souhb,f ;
btfsc status,c ;是否大于100℃?
goto dbtbcd ;否,转向双字节二进制数转化成压缩BCD码
movlw 71h ;是,rlth:rlt;souh:sou分别赋值71h,送显,显示FFF.F℃
movwf sou ;
movwf souh ;
movwf rlt ;
movwf rlth ;
goto display ;
;***********双字节二进制数转化成压缩BCD码***************
;入口参数:原二进制数在souh:sou中。
;出口参数:结果在rlt:souh:sou中。
dbtbcd movf sou,w ;
movwf temp2 ;
movf souh,w ;
movwf temp3 ;
clrf sou ;
clrf souh ;
clrf rlt ;
bcf status,c ;
movlw .16 ;
movwf cnt ;
loopc1 rlf temp2,f ;
rlf temp3,f ;
rlf sou,f ;
rlf souh,f ;
rlf rlt,f ;
decfsz cnt,f ;
goto adjdec1 ;
goto dcobcdtu ;整个双字节二进制数转化成压缩BCD码结束
;跳转到双字节压缩BCD码转化为非压缩BCD码
adjdec1 movlw sou ;
movwf fsr ;
call adjbcd1 ;调整rlt
movlw souh ;
movwf fsr ;
call adjbcd1 ;调整rlth
movlw rlt ;
movwf fsr ;
call adjbcd1 ;调整temp1
goto loopc1 ;
;********************调整BCD********************
adjbcd1 movlw 03h ;
addwf indf,w ;低四位加3
movwf temp1 ;暂存
btfsc temp1,3 ;结果大于7,
movwf indf ;则存起来
movlw 30h ;
addwf indf,w ;高四位加3
movwf temp1 ;
btfsc temp1,7 ;结果大于7,
movwf indf ;则存起来
retlw 0 ;
;*****************双字节压缩BCD码转化为非压缩BCD码************
;入口参数:原BCD码数在souh:sou中。
;出口参数:结果在rlth:rlt:souh:sou中。
;说明:由于温度不大于100.0℃,精确到0.1℃,所以取四位BCD码
dcobcdtu swapf souh,w ;
andlw 0fh ;
movwf rlth ;
movlw 0fh ;
andwf souh,w ;
movwf rlt ;
swapf sou,w ;
andlw 0fh ;
movwf souh ;
movlw 0fh ;
andwf sou,f ;
;****************非压缩BCD码转化为七段码*****************
movf rlth,w ;
call convert ;
movwf rlth ;
movf rlt,w ;
call convert ;
movwf rlt ;
movf souh,w ;
call convert ;
movwf souh ;
movf sou,w ;
call convert ;
movwf sou ;
goto display ;
convert addwf pcl,f ;把W内容叠加到PC的低8位上
retlw 03fh ;返回字符“0”的笔段码(bit7-bit0=a,b,……dp)
retlw 06h ;“1”的笔段码
retlw 5bh ;“2”的笔段码
retlw 4fh ;“3”的笔段码
retlw 66h ;“4”的笔段码
retlw 6dh ;“5”的笔段码
retlw 7dh ;“6”的笔段码
retlw 07h ;“7”的笔段码
retlw 7fh ;“8”的笔段码
retlw 6fh ;“9”的笔段码
;*******************发送显示************************
display movf sou,w ;
call out_in ;
movf souh,w ;
call out_in ;
movf rlt,w ;
call out_in ;
movf rlth,w ;
call out_in ;
goto delay ;
out_in movwf sspbuf ;送数据给SSPBUF后开始发送
loop1 bcf status,rp1 ; 选RAM体1
bsf status,rp0 ;
btfss sspstat,bf ;查询发送/接收完否
goto loop1 ;否,继续查询
bcf status,rp0 ;是,选RAM体1
movf sspbuf,w ;从SSPBUF中取出接到数据,即使数据无用也应腾空缓冲器
goto delay ; 跳转到延时
;********************延时1秒********************
delay
lp0 movlw 0ah ;
movlw 0ffh ;
movwf 32h ;
movwf 30h ;
lp1 movlw 0ffh ;
movwf 31h ;
lp2 decfsz 31h ;
goto lp2 ;
decfsz 30h ;
goto lp1 ;
decfsz 32h ;
goto lp0 ;
goto start ;
end