PIC16F877A控制DS18B20汇编程序
2013-03-26


;************************************************************************
;功能实现:通过DS18B20来读取温度,显示在2位LED上,精确到1度
;硬件连接:(1)RC0-RC7接共阳数码管的段码A-H
;RA0-RA3接共阳数码管的位码DIG0-DIG3
;***********************************************************************
;***********************************************************************
;定义单片机型号为PIC16F877A
;程序包含文件:P16F877A.INC
;定义配置字
;***********************************************************************
LISTP=16F877A;定义本程序所使用的芯片为PIC16F877A
#INCLUDE "P16F877A.INC";定义本程序包含该文件
__CONFIG3F72H;晶振配置HS,看门狗禁止,上电延时使能,掉电复位使能
;低电压编程禁止,代码不保护
#DEFINEDQPORTB,2
#DEFINEDIRTRISB,2
CBLOCK20H
Y1
Y2
COUNT1
COUNT2
COMD
DATE
BIN_L;要进行转换的字节
GE;转换后的个位
SHI;转换后的十位
DATE_L
DATE_H
ENDC
;***********************************************************************
;复位矢量定义(对于16F877A)
;***********************************************************************
ORG0000H;复位矢量地址
GOTOMAIN;程序跳转到MAIN主程序
;----------------------------------------------------------------------
;***********************************************************************
;主程序区
;***********************************************************************
ORG0005H
MAIN
NOP
CALLINTIAL
STARTBTFSSDQ;数据线空闲状态为高电平
GOTO$-1
CALLRESET;复位DS18B20
MOVLW0CCH;跳过读ROM命令
CALLWR18B20
MOVLW44H;温度转换
CALLWR18B20
CALLDELAY_750US;延时750us
CALLRESET;复位DS18B20
MOVLW0CCH;跳过读ROM命令
CALLWR18B20
MOVLW0BEH;读内部RAM中的9字节内容
CALLWR18B20
NOP
CALLRE18B20;读数据
MOVFDATE,W
MOVWFDATE_L;读低8位
CALLRE18B20;读数据
MOVFDATE,W
MOVWFDATE_H;读高8位
MOVFDATE_L,W
;------------------------显示处理--------------------------------------
RRFDATE_H,F
RRFDATE_L,F
RRFDATE_H,F
RRFDATE_L,F
RRFDATE_H,F
RRFDATE_L,F
RRFDATE_H,F
RRFDATE_L,F
MOVFDATE_L,W
MOVWFBIN_L;把高8位的低4位和低8位的高4位组合起来
CALLDISPLAY;调用数码管显示程序
GOTOSTART
;=======================================================================
;***********************************************************************
;初始化和消影
;***********************************************************************
INTIALBSFSTATUS,RP0;定义当前体为体1,对方向寄存器进行修改
MOVLW07H
MOVWFADCON1;关闭A口的模拟通道
MOVLW00H
MOVWFTRISC;段码显示口为输出口
MOVLW0F0H
ANDWFTRISA,1;使位码(RA0-RA3)为输出口
BSFDIR;使数据线为输入
BCFSTATUS,RP0;使当前体为体0
MOVLW0FFH;关闭段码
MOVWFPORTC
MOVLW0FFH;关闭位码
MOVWFPORTA
BTFSSDQ;数据线空闲状态为高电平
GOTO$-1
CALLRESET;复位DS18B20
MOVLW0CCH;跳过读ROM命令
CALLWR18B20
MOVLW44H;温度转换
CALLWR18B20
CALLDELAY_750US;延时750us
CALLRESET;复位DS18B20
MOVLW0CCH;跳过读ROM命令
CALLWR18B20
MOVLW0BEH;读内部RAM中的9字节内容
CALLWR18B20
NOP
NOP
CALLRE18B20;读数据
CALLRE18B20;读数据
CALLDELAY_MAX;延时600ms
CALLDELAY_MAX
CALLDELAY_MAX
RETLW00H
;=======================================================================
;***********************************************************************
;显示所测得的温度子程序
;***********************************************************************
DISPLAY
CALL_BCD
MOVFSHI,W
ANDLW0FH
CALLTABLE;调用查表指令
MOVWFPORTC;显示十位段码
BCFPORTA,0;选通十位显示位码
CALLDELAY
BSFPORTA,0;关闭十位显示位码
MOVFGE,W
ANDLW0FH
CALLTABLE;调用查表指令
MOVWFPORTC;显示个位段码
BCFPORTA,1;选通个位显示位码
CALLDELAY
BSFPORTA,1;关闭个位显示位码
RETLW00H
;=======================================================================
;***********************************************************************
;二进制转BCD码
;***********************************************************************
_BCDCLRFSHI;保存地址清零
CLRFGE
MOVFBIN_L,F;组合码自己给自己赋值,测试是否为0
SKPNZ;不为0则跳到下一步
RETLW00H
SHI_MOVLWD'10'
SUBWFBIN_L,W;BIN_L减10,结果存到W寄存器
BTFSSSTATUS,C;执行减法后,如果无借位
GOTOGE_
MOVWFBIN_L
INCFSHI
GOTOSHI_ 
GE_MOVFBIN_L,W
MOVWFGE
RETLW00H
;=======================================================================
;***********************************************************************
;延时200ms
;***********************************************************************
DELAY_MAX
MOVLW0FFH
MOVWFY1
MOVLW0FFH
MOVWFY2
DECFSZY2
GOTO$-1
DECFSZY1
GOTO$-5
RETLW00H
;=======================================================================
;***********************************************************************
;延时6ms
;***********************************************************************
DELAY
MOVLW03FH
MOVWFY1
MOVLW020H
MOVWFY2
DECFSZY2
GOTO$-1
DECFSZY1
GOTO$-5
RETLW00H
;=======================================================================
;***********************************************************************
;延时750us子程序
;***********************************************************************
DELAY_750US
MOVLW09H
MOVWFY1
MOVLW01AH
MOVWFY2
DECFSZY2
GOTO$-1
DECFSZY1
GOTO$-5
RETLW00H
;=======================================================================
;***********************************************************************
;查表子程序,用于显示段码数字
;数码管为共阳数码管
;***********************************************************************
TABLE
ADDWFPCL,F
RETLW0C0H;"0"
RETLW0F9H;"1"
RETLW0A4H;"2"
RETLW0B0H;"3"
RETLW99H;"4"
RETLW92H;"5"
RETLW82H;"6"
RETLW0F8H;"7"
RETLW80H;"8"
RETLW90H;"9"
;=======================================================================
;***********************************************************************
;DS18B20复位和应答子程序
;***********************************************************************
RESETBSFSTATUS,RP0;使当前体为体1
BCFDIR;使数据位为输出
BCFSTATUS,RP0;使当前体为体0
BSFDQ;拉高数据位
NOP;空循环
BCFDQ;拉低数据位
MOVLWD'200';延时600us
MOVWFY1
DECFSZY1
GOTO$-1
BSFSTATUS,RP0;使当前体为体1
BSFDIR;使数据位为输入
BCFSTATUS,RP0;使当前体为体0
MOVLWD'30';延时90us
MOVWFY1
DECFSZY1
GOTO$-1
BTFSCDQ;主机接收到低电平应答脉冲,跳转到下一句
GOTORESET
MOVLWD'80';延时240us
MOVWFY1
DECFSZY1
GOTO$-1
BTFSSDQ;主机接收到高电平应答脉冲,跳转到下一句
GOTORESET
RETLW00H;返回00H,复位应答结束
;========================================================================
;***********************************************************************
;写DS18B20子程序
;***********************************************************************
WR18B20
MOVWFCOMD;把要写的数据写到COMD内
MOVLWD'8'
MOVWFCOUNT2;大循环8次
WR0BSFSTATUS,RP0;使当前体为体1
BCFDIR;使数据位为输出
BCFSTATUS,RP0;使当前体为体0
BCFDQ;拉低数据线
NOP
NOP
MOVLWD'2'
MOVWFCOUNT1;延时9us
WR1DECFSZCOUNT1,1
GOTOWR1
BTFSCCOMD,0;COMD最低位为0则跳转到下一句
BSFDQ;拉高数据线
BTFSCCOMD,0;COMD最低位为0则跳转到下一句
NOP
BCFSTATUS,C;进位位置0
RRFCOMD,1;带进位位,COMD向右移一位
MOVLWD'20';延时60us
MOVWFCOUNT1
WR2DECFSZCOUNT1,1
GOTOWR2
BSFDQ;拉高数据线,空闲状态
BSFSTATUS,RP0;使当前体为体1
BSFDIR;使数据位为输入
BCFSTATUS,RP0;使当前体为体0
DECFSZCOUNT2,1;8次循环到了则跳出
GOTOWR0
RETLW00H
;=======================================================================
;***********************************************************************
;读18B20子程序
;***********************************************************************
RE18B20
MOVLW8
MOVWFCOUNT2
RE0BSFSTATUS,RP0;使当前体为体1
BCFDIR;使数据位为输出
BCFSTATUS,RP0;使当前体为体0
BCFDQ
MOVLW2
MOVWFCOUNT1
RE1DECFSZCOUNT1,1
GOTORE1
BSFSTATUS,RP0;使当前体为体1
BSFDIR;使数据位为输入
BCFSTATUS,RP0;使当前体为体0 
NOP
BTFSSDQ;如果数据线为高电平,则C=1
BCFSTATUS,C
BTFSCDQ;如果数据线为低电平,则C=0
BSFSTATUS,C
RRFDATE,1;数据依次存在DATE上
MOVLWD'20';延时60us
MOVWFCOUNT1
RE2DECFSZCOUNT1,1
GOTORE2
DECFSZCOUNT2,1
GOTORE0
BSFDQ
RETLW00H
;=======================================================================
;=======================================================================
END;程序结束


可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号