技术热线: 4007-888-234

基于Pic16f873的数字温度计及其源程序

更新时间: 2019-03-23
阅读量:1957

基于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