具体算法分析,会在后文中提到。
DSl820工作过程中的协议
初始化->RoM操作命令->存储器操作命令->处理数据
1初始化
单总线上的所有处理均从初始化开始
2ROM操作品令
总线主机检测到DSl820的存在便可以发出ROM操作命令之一这些命令如
指令 代码
ReadROM(读ROM) [33H]
MatchROM(匹配ROM) [55H]
SkipROM(跳过ROM] [CCH]
SearchROM(搜索ROM) [F0H]
Alarmsearch(告警搜索) [ECH]
3存储器操作命令
指令 代码
WriteScratchpad(写暂存存储器) [4EH]
ReadScratchpad(读暂存存储器) [BEH]
CopyScratchpad(复制暂存存储器) [48H]
ConvertTemperature(温度变换) [44H]
RecallEPROM(重新调出) [B8H]
ReadPowersupply(读电源) [B4H]
温度传感器与单片机通讯时序
2.温度转换算法及分析
由于DS18B20转换后的代码并不是实际的温度值,所以要进行计算转换。
温度高字节(MSByte)高5位是用来保存温度的正负(标志为S的bit11~bit15),高字节(MSByte)低3位和低字节来保存温度值(bit0~bit10)。
其中低字节(LSByte)的低4位来保存温度的小数位(bit0~bit3)。
由于本程序采用的是0.0625的精度,小数部分的值,可以用后四位代表的实际数值乘以0.0625,得到真正的数值,数值可能带几个小数位,所以采取小数舍入,保留一位小数即可。
也就说,本系统的温度精确到了0.1度。
算法核心:
首先程序判断温度是否是零下,如果是,则DS18B20保存的是温度的补码值,需要对其低8位(LSByte)取反加一变成原码。
处理过后把DS18B20的温度Copy到单片机的RAM中,里面已经是温度值的Hex码了,然后转换Hex码到BCD码,分别把小数位,个位,十位,百位的BCD码存入RAM中。
由于百位没有用,默认情况是置为0A,在显示屏上没有任何显示。
温度算法核心代码
DATA_DEAL:
MOV A,TEMPERATURE_H;TEMPERATURE_H存放的是DS18B20转换后的高8位的值(上图的MSByte)ANL A,#80H ;判温度是否零下
JZ TEMPC1 ;A为0,说明是正数,跳往TEMPC1,如果是负数,则对低8为进行补码处理
CLR C
MOV A,TEMPERATURE_L ;为负数,对低8位(上图的LSByte)求补
CPL A ;取反加1
ADD A,#01H
MOV TEMPERATURE_L,A ;取补码后存回TEMPERATURE_L,此时TEMPERATURE_L里面的值就可以表示温度了 MOV A,TEMPERATURE_H
CPL A
ADDC A,#00H ;高位TEMPERATURE_H取反,加上从低位TEMPERATURE_L进来的位
MOV TEMPERATURE_H,A ;写回TEMPERATURE_H
MOV TEMPERATURE_HC,#0BH
SJMP TEMPC11
TEMPC1:
MOV TEMPERATURE_HC,#0AH
TEMPC11:
MOV A,TEMPERATURE_HC
SWAP A
MOV TEMPERATURE_HC,A
MOV A,TEMPERATURE_L
ANL A,#0FH ;取A低4位(小数位,单位是0.0625),得出来的数要乘以0.0625,通过查表来算出值
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR ;查表
MOV TEMPERATURE_LC,A ;TEMPERATURE_LC的低四位保存小数部分BCD
MOV DIS_BUF_X,A ;小数位的BCD码送入显示buffer中
MOV A,TEMPERATURE_L ;整数部分
ANL A,#0F0H ;得到个位单个数值
SWAP A ;SWAP后就得到个位真正的个位
MOV TEMPERATURE_L,A
MOV A,TEMPERATURE_H
ANL A,#0FH
SWAP A
ORL A,TEMPERATURE_L
MOV TEMPERATURE_ZH,A ;组合后的值存入TEMPERATURE_ZH
LCALL HtoB ;转换HEx值成为BCD码
MOV TEMPERATURE_L,A ;TEMPERATURE_L目前存入的是十位和个位的BCD编码
ANL A,#0F0H
SWAP A
ORL A,TEMPERATURE_HC ;TEMPERATURE_HC低4位存放十位数BCD
MOV TEMPERATURE_HC,A
MOV A,TEMPERATURE_L
ANL A,#0FH
SWAP A ;TEMPERATURE_LC高4位存放个位数BCD
ORL A,TEMPERATURE_LC
MOV TEMPERATURE_LC,A
MOV A,R7
JZ TEMPC12
ANL A,#0FH
SWAP A
MOV R7,A
MOV A,TEMPERATURE_HC ;TEMPERATURE_HC高4位存放百位数BCD
ANL A,#0FH
ORL A,R7
MOV TEMPERATURE_HC,A
TEMPC12:
RET
;小数部分码表
TEMPDOTTAB:
DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H,06H,07H,08H,08H,09H,09H
结果温度值的BCD码存放到TEMPERATURE_HC(百位和十位),TEMPERATURE_LC(个位和小数位)中
七.硬件设计说明
1.系统总体电路图
2.各个模块电路图
输入系统
1. 键盘模块
我们用的下面四个独立键盘中的三个,分别是:
K2,K3,K4。
1. 温度测量模块
DS18B20通过P3.3口和AT89S52进行通讯。
输出系统
1. 继电器模块
下图是一个蜂鸣器和一个继电器的图,我们只用到了继电器的图,继电器和单片机的P1.3口进行通讯。
1. 显示模块
该显示模块的动态显示数码管,我们用到前面四个数码管,P0口是送字符的,P2口是用来位选数码管的。
芯片系统
本系统采用的是AT89S52芯片。
下面是它的引脚图。
八.软件设计说明
本系统采用的是循环查询方式,来显示和控制温度的。
1.总模块的流程图
2.各个模块的流程图
读取温度DS18B20模块的流程
键盘扫描处理流程
九.操作指引
按键功能
1. Enter → P1.5(k2)2. Up → P1.6(k3)3. Down → P1.7(k4)
显示温度
1. 未插DS18B20时,数码管显示错误888.8.
2. 插入DS18B20是,数码管显示当前温度XX.X
设定温度
1.按下Enter,数码管温度显示停止,显示的数字变的比以前亮。
2.这时可以按Up和Down来调节当前温度。
3.调节好后,按Enter退出。
这时数字变的又暗了,数码管继续显示当前温度
继电器随着设定的温度,依据情况跳变。
十.参考文献
[1]. 单片机原理与应用技术.江力主编.清华大学出版社.2006
[2]. 微型计算机接口技术.王兆月等编著.机械工业出版社.2006
[3]. 数字电子技术.江晓安等编著.西安电子科技大学出版社.1993
[4]. ME300B说明书.伟纳电子编著.伟纳电子出版.2006
[5]. DS18B20官方英文文档.DS18B20官方英文站点下载.
程序源代码
TEMPERATURE_LDATA31H;DS18B20低8位Buffer
TEMPERATURE_HDATA30H;DS18B20高8位Buffer
TEMPERATURE_HCDATA32H;计算后的百位和十位的BCD码存放BUFFER
TEMPERATURE_LCDATA33H;计算后的个位和小数位的BCD码存放BUFFER
TEMPERATURE_ZHDATA34H;计算后十位和个位HEX码的存放BUFFER
DIS_BUF_XDATA35H;数码管小数位Buffer
DIS_BUF_GDATA36H;数码管个位Buffer
DIS_BUF_SDATA37H;数码管十位Buffer
DIS_BUF_BDATA38H;数码管百位Buffer
KEY_BUF_GDATA39H;键盘输入后,的个位值
KEY_BUF_SDATA49H;键盘输入后,的十位值
KEY_BUF_BDATA41H;键盘输入后,的百位值
K_UPEQUP1.5;上调按钮
K_DOWNEQUP1.6;下调按钮
K_ENTEREQUP1.7;输入数据确认按钮
P_DS18B20EQUP3.3;读取DS18B20的输入端口
P_SWITCHEQUP1.3;继电器控制端口,1-风扇,0-电炉
FLAGEQU20H.0;标志位,确定是否存在DS18B20
ENTER_FLAGEQU20H.1;键盘输入的标志位,为0说明键盘正在输入,为1说明键盘输入退出
;程序开始执行
ORG0000H
LJMPMAIN
ORG0100H
MAIN:
MOVSP,#60H;初始化
MOVKEY_BUF_G,#00H;由于KEY_BUF是由用户输入的,所以先赋值初始化
MOVKEY_BUF_S,#00H
MOVKEY_BUF_B,#00H
NEXT:
LCALLREAD_TEMP;调用读温度子程序
JBFLAG,NORMAL;判断是否有DS18B20的存在
CALLERR;不存在时显示错误信息
AJMPNEXT
NORMAL:
LCALLDATA_DEA;处理从DS18B20得到的数据
LCALLSET_DIS_BUF;赋值给DIS_BUF_X,G,S,B
LCALLDISPLAY;调用数码管显示子程序
LCALLSCAN_KEY;扫描键盘
LCALLSWITCH;处理继电器
AJMPNEXT
;程序名称:
ERR
;功能:
程序出错处理,显示四个8,即8888
;入口参数:
无
;出口参数:
DIS_BUF_X,DIS_BUF_G,DIS_BUF_S,DIS_BUF_B
ERR:
MOVDIS_BUF_X,#08H;如果没有找到DS18B20,那么就显示错误,错误显示为888
MOVDIS_BUF_G,#08H
MOVDIS_BUF_S,#08H
MOVDIS_BUF_B,#08H
LCALLDISPLAY
RET
;程序名称:
DATA_DEAL
;功能:
处理采集后的的数据
;入口参数:
TEMPERATURE_L
;出口参数:
DIS_BUF_G,DIS_BUF_S,DIS_BUF_B
DATA_DEAL:
MOVA,TEMPERATURE_H;判温度是否零下
ANLA,#80H
JZTEMPC1;A为0,说明是正数,跳往TEMPC1,如果是负数,则对低8为进行补码处理
CLRC
MOVA,TEMPERATURE_L;二进制数求补(双字节)
CPLA;取反加1
ADDA,#01H
MOVTEMPERATURE_L,A;取补码后存回TEMPERATURE_L,此时TEMPERATURE_L里面的值就可以表示温
;度了,不过还要继续处理一下。
MOVA,TEMPERATURE_H
CPLA
ADDCA,#00H;高位TEMPERATURE_H取反,加上从低位TEMPERATURE_L进来的位
MOVTEMPERATURE_H,A;写回TEMPERATURE_H
MOVTEMPERATURE_HC,#0BH
SJMPTEMPC11
TEMPC1:
MOVTEMPERATURE_HC,#0AH
TEMPC11:
MOVA,TEMPERATURE_HC
SWAPA
MOVTEMPERATURE_HC,A
MOVA,TEMPERATURE_L
ANLA,#0FH;取A低4位(小数位,单位是0.0625),得出来的数要乘以0.0625,通过查表来算出值
MOVDPTR,#TEMPDOTTAB
MOVCA,@A+DPTR;查表
MOVTEMPERATURE_LC,A;TEMPERATURE_LCLOW=小数部分BCD
MOVDIS_BUF_X,A;小数位的BCD码送入显示buffer中
MOVA,TEMPERATURE_L;整数部分
ANLA,#0F0H;得到个位‘单个数值
SWAPA;SWAP后就得到个位真正的个位
MOVTEMPERATURE_L,A
MOVA,TEMPERATURE_H
ANLA,#0FH
SWAPA
ORLA,TEMPERATURE_L
MOVTEMPERATURE_ZH,A;组合后的值存入TEMPERATURE_ZH
LCALLHtoB;转换HEx值成为BCD码
MOVTEMPERATURE_L,A;TEMPERATURE_L目前存入的是十位和个位的BCD编码
ANLA,#0F0H
SWAPA
ORLA,TEMPERATURE_HC;TEMPERATURE_HCLOW位=十位数BCD
MOVTEMPERATURE_HC,A
MOVA,TEMPERATURE_L
ANLA,#0FH
SWAPA;TEMPERATURE_LCHI位=个位数BCD
ORLA,TEMPERATURE_LC
MOVTEMPERATURE_LC,A
MOVA,R7
JZTEMPC12
ANLA,#0FH
SWAPA
MOVR7,A
MOVA,TEMPERATURE_HC;TEMPERATURE_HCHI=百位数BCD
ANLA,#0FH
ORLA,R7
MOVTEMPERATURE_HC,A
TEMPC12:
RET
;小数部分码表
TEMPDOTTAB:
DB00H,01H,01H,02H,03H,03H,04H,04H,05H,06H,06H,07H,08H,08H,09H,09H
;0.0625->00H
;0.0625*2=0.125->01H
;0.0625*3=0.1875->01H
;0.0625*4=0.25->02H
;0.0625*5=0.3125->03H
;以此类推..........
;程序名称:
HtoB
;功能:
十六进制转BCD
;入口参数:
A
;出口参数:
R7
HtoB:
MOVB,#064H;100
DIVAB;a/100
MOVR7,A;
MOVA,#0AH
XCHA,B
DIVAB
SWAPA
ORLA,B
RET
;程序名称:
INIT_TEMP
;功能:
初始化DS18B20,确定DS18B20是否是存在的
;入口参数:
无
;出口参数:
FLAG
INIT_TEMP:
SETBP_DS18B20
NOP
CLRP_DS18B20;主机发出延时537微秒的复位低脉冲
MOVR0,#6BH
MOVR1,#04H
TSR1:
DJNZR0,$
MOV40,#6BH
DJNZR1,TSR1
SETBP_DS18B20;然后拉高数据线,释放总线进入接受状态
NO