;***********************************************
;功能实现:通过DS18B20来读取温度,显示在2位LED上,精确到1度
;硬件连接:(1)RC0-RC7接共阳数码管的段码A-H
; RA0-RA3接共阳数码管的位码DIG0-DIG3
;***************************************************
;****************************************************
;定义单片机型号为PIC16F877A
;程序包含文件:P16F877A.INC
;定义配置字
;*********************************************************
LIST P=16F877A ;定义本程序所使用的芯片为PIC16F877A
#INCLUDE "P16F877A.INC" ;定义本程序包含该文件
__CONFIG 3F72H ;晶振配置HS,看门狗禁止,上电延时使能,掉电复位使能
;低电压编程禁止,代码不保护
#DEFINE DQ PORTB,2
#DEFINE DIR TRISB,2
CBLOCK 20H
Y1
Y2
COUNT1
COUNT2
COMD
DATE
BIN_L ;要进行转换的字节
GE ;转换后的个位
SHI ;转换后的十位
DATE_L
DATE_H
ENDC
;*****************************************************
;复位矢量定义(对于16F877A)
;***************************************************
ORG 0000H ;复位矢量地址
GOTO MAIN ;程序跳转到MAIN主程序
;----------------------------------------------------------------------
;***************************************************
;主程序区
;************************************************
ORG 0005H
MAIN
NOP
CALL INTIAL
START BTFSS DQ ;数据线空闲状态为高电平
GOTO $-1
CALL RESET ;复位DS18B20
MOVLW 0CCH ;跳过读ROM命令
CALL WR18B20
MOVLW 44H ;温度转换
CALL WR18B20
CALL DELAY_750US ;延时750us
CALL RESET ;复位DS18B20
MOVLW 0CCH ;跳过读ROM命令
CALL WR18B20
MOVLW 0BEH ;读内部RAM中的9字节内容
CALL WR18B20
NOP
CALL RE18B20 ;读数据
MOVF DATE,W
MOVWF DATE_L ;读低8位
CALL RE18B20 ;读数据
MOVF DATE,W
MOVWF DATE_H ;读高8位
MOVF DATE_L,W
;------------------------显示处理--------------------------------------
RRF DATE_H,F
RRF DATE_L,F
RRF DATE_H,F
RRF DATE_L,F
RRF DATE_H,F
RRF DATE_L,F
RRF DATE_H,F
RRF DATE_L,F
MOVF DATE_L,W
MOVWF BIN_L ;把高8位的低4位和低8位的高4位组合起来
CALL DISPLAY ;调用数码管显示程序
GOTO START
;=================================================
;************************************************
;初始化和消影
;***********************************************************
INTIAL BSF STATUS,RP0 ;定义当前体为体1,对方向寄存器进行修改
MOVLW 07H
MOVWF ADCON1 ;关闭A口的模拟通道
MOVLW 00H
MOVWF TRISC ;段码显示口为输出口
MOVLW 0F0H
ANDWF TRISA,1 ;使位码(RA0-RA3)为输出口
BSF DIR ;使数据线为输入
BCF STATUS,RP0 ;使当前体为体0
MOVLW 0FFH ;关闭段码
MOVWF PORTC
MOVLW 0FFH ;关闭位码
MOVWF PORTA
BTFSS DQ ;数据线空闲状态为高电平
GOTO $-1
CALL RESET ;复位DS18B20
MOVLW 0CCH ;跳过读ROM命令
CALL WR18B20
MOVLW 44H ;温度转换
CALL WR18B20
CALL DELAY_750US ;延时750us
CALL RESET ;复位DS18B20
MOVLW 0CCH ;跳过读ROM命令
CALL WR18B20
MOVLW 0BEH ;读内部RAM中的9字节内容
CALL WR18B20
NOP
NOP
CALL RE18B20 ;读数据
CALL RE18B20 ;读数据
CALL DELAY_MAX ;延时600ms
CALL DELAY_MAX
CALL DELAY_MAX
RETLW 00H
;===================================================
;**************************************************
;显示所测得的温度子程序
;**********************************************
DISPLAY
CALL _BCD
MOVF SHI,W
ANDLW 0FH
CALL TABLE ;调用查表指令
MOVWF PORTC ;显示十位段码
BCF PORTA,0 ;选通十位显示位码
CALL DELAY
BSF PORTA,0 ;关闭十位显示位码
MOVF GE,W
ANDLW 0FH
CALL TABLE ;调用查表指令
MOVWF PORTC ;显示个位段码
BCF PORTA,1 ;选通个位显示位码
CALL DELAY
BSF PORTA,1 ;关闭个位显示位码
RETLW 00H[page]
;======================================================
;*******************************************************
;二进制转BCD码
;****************************************************
_BCD CLRF SHI ;保存地址清零
CLRF GE
MOVF BIN_L,F ;组合码自己给自己赋值,测试是否为0
SKPNZ ;不为0则跳到下一步
RETLW 00H
SHI_ MOVLW D\'10\'
SUBWF BIN_L,W ;BIN_L减10,结果存到W寄存器
BTFSS STATUS,C ;执行减法后,如果无借位
GOTO GE_
MOVWF BIN_L
INCF SHI
GOTO SHI_
GE_ MOVF BIN_L,W
MOVWF GE
RETLW 00H
;=================================================
;**********************************************************
;延时200ms
;************************************************************
DELAY_MAX
MOVLW 0FFH
MOVWF Y1
MOVLW 0FFH
MOVWF Y2
DECFSZ Y2
GOTO $-1
DECFSZ Y1
GOTO $-5
RETLW 00H
;==========================================
;***************************************************
;延时6ms
;*****************************************************
DELAY
MOVLW 03FH
MOVWF Y1
MOVLW 020H
MOVWF Y2
DECFSZ Y2
GOTO $-1
DECFSZ Y1
GOTO $-5
RETLW 00H
;==============================================
;********************************************
;延时750us子程序
;**********************************************************
DELAY_750US
MOVLW 09H
MOVWF Y1
MOVLW 01AH
MOVWF Y2
DECFSZ Y2
GOTO $-1
DECFSZ Y1
GOTO $-5
RETLW 00H
;=========================================
;*******************************************************
;查表子程序,用于显示段码数字
;数码管为共阳数码管
;********************************************************
TABLE
ADDWF PCL,F
RETLW 0C0H ;"0"
RETLW 0F9H ;"1"
RETLW 0A4H ;"2"
RETLW 0B0H ;"3"
RETLW 99H ;"4"
RETLW 92H ;"5"
RETLW 82H ;"6"
RETLW 0F8H ;"7"
RETLW 80H ;"8"
RETLW 90H ;"9"
;===============================================
;***********************************************************
;DS18B20复位和应答子程序
;************************************************************
RESET BSF STATUS,RP0 ;使当前体为体1
BCF DIR ;使数据位为输出
BCF STATUS,RP0 ;使当前体为体0
BSF DQ ;拉高数据位
NOP ;空循环
BCF DQ ;拉低数据位
MOVLW D\'200\' ;延时600us
MOVWF Y1
DECFSZ Y1
GOTO $-1
BSF STATUS,RP0 ;使当前体为体1
BSF DIR ;使数据位为输入
BCF STATUS,RP0 ;使当前体为体0
MOVLW D\'30\' ;延时90us
MOVWF Y1
DECFSZ Y1
GOTO $-1
BTFSC DQ ;主机接收到低电平应答脉冲,跳转到下一句
GOTO RESET
MOVLW D\'80\' ;延时240us
MOVWF Y1
DECFSZ Y1
GOTO $-1
BTFSS DQ ;主机接收到高电平应答脉冲,跳转到下一句
GOTO RESET
RETLW 00H ;返回00H,复位应答结束
;=================================================
;***********************************************************
;写DS18B20子程序
;************************************************************
WR18B20
MOVWF COMD ;把要写的数据写到COMD内
MOVLW D\'8\'
MOVWF COUNT2 ;大循环8次
WR0 BSF STATUS,RP0 ;使当前体为体1
BCF DIR ;使数据位为输出
BCF STATUS,RP0 ;使当前体为体0
BCF DQ ;拉低数据线
NOP
NOP
MOVLW D\'2\'
MOVWF COUNT1 ;延时9us
WR1 DECFSZ COUNT1,1
GOTO WR1
BTFSC COMD,0 ;COMD最低位为0则跳转到下一句
BSF DQ ;拉高数据线
BTFSC COMD,0 ;COMD最低位为0则跳转到下一句
NOP
BCF STATUS,C ;进位位置0
RRF COMD,1 ;带进位位,COMD向右移一位
MOVLW D\'20\' ;延时60us
MOVWF COUNT1
WR2 DECFSZ COUNT1,1
GOTO WR2
BSF DQ ;拉高数据线,空闲状态
BSF STATUS,RP0 ;使当前体为体1
BSF DIR ;使数据位为输入
BCF STATUS,RP0 ;使当前体为体0
DECFSZ COUNT2,1 ;8次循环到了则跳出
GOTO WR0
RETLW 00H
;====================================================
******************
;读18B20子程序
;**********************************************************
RE18B20
MOVLW 8
MOVWF COUNT2
RE0 BSF STATUS,RP0 ;使当前体为体1
BCF DIR ;使数据位为输出
BCF STATUS,RP0 ;使当前体为体0
BCF DQ
MOVLW 2
MOVWF COUNT1
RE1 DECFSZ COUNT1,1
GOTO RE1
BSF STATUS,RP0 ;使当前体为体1
BSF DIR ;使数据位为输入
BCF STATUS,RP0 ;使当前体为体0
NOP
BTFSS DQ ;如果数据线为高电平,则C=1
BCF STATUS,C
BTFSC DQ ;如果数据线为低电平,则C=0
BSF STATUS,C
RRF DATE,1 ;数据依次存在DATE上
MOVLW D\'20\' ;延时60us
MOVWF COUNT1
RE2 DECFSZ COUNT1,1
GOTO RE2
DECFSZ COUNT2,1
GOTO RE0
BSF DQ
RETLW 00H
;======================================================
;==============================================
END ;程序结束
上一篇:PIC16F877单片机与PC机通讯的汇编程序
下一篇:PIC单片机的浮点数格式及转换
推荐阅读最新更新时间:2024-03-16 13:14