DS18B20的调试总结和程序
温度传感器ds18b20实验报告
温度传感器ds18b20实验报告温度传感器DS18B20实验报告引言温度传感器在现代生活中扮演着重要的角色,它们被广泛应用于各种领域,包括工业、医疗、农业等。
DS18B20是一种数字温度传感器,具有精准的测量能力和数字输出,因此备受青睐。
本实验旨在通过对DS18B20温度传感器的测试和分析,探讨其性能和应用。
实验目的1. 了解DS18B20温度传感器的工作原理和特性。
2. 测试DS18B20温度传感器的测量精度和响应速度。
3. 探讨DS18B20温度传感器在实际应用中的优缺点。
实验器材1. DS18B20温度传感器2. Arduino开发板3. 4.7kΩ电阻4. 连接线5. 电脑实验步骤1. 将DS18B20温度传感器连接到Arduino开发板上,并接入4.7kΩ电阻。
2. 编写Arduino程序,通过串口监视器输出DS18B20传感器的温度数据。
3. 将DS18B20传感器置于不同的温度环境中,记录其输出的温度数据。
4. 分析DS18B20传感器的测量精度和响应速度。
5. 探讨DS18B20传感器在实际应用中的优缺点。
实验结果经过实验测试,DS18B20温度传感器表现出了较高的测量精度和响应速度。
在不同温度环境下,其输出的温度数据与实际温度基本吻合,误差较小。
此外,DS18B20传感器具有数字输出,易于与各种微控制器和单片机进行连接,应用范围广泛。
然而,DS18B20传感器在极端温度环境下可能出现测量误差,且价格较高,需要根据实际需求进行选择。
结论DS18B20温度传感器具有较高的测量精度和响应速度,适用于各种温度测量场景。
然而,在选择和应用时需要考虑其价格和适用范围,以确保满足实际需求。
希望本实验能够为DS18B20温度传感器的应用提供参考和借鉴,推动其在各个领域的发展和应用。
DS18B20操作程序
WRITE: ;向ds1820写操作命令子程序 CLR EA MOV R3,#8 ;写入ds1820的bit数,一个字节8个bit WR1:SETB DQ MOV R4,#8 RRC A ;把一个字节data(A)分成8个bit环移给C CLR DQ ;开始写入ds1820总线要处于复位(低)状态 WR2:DJNZ R4,WR2 ;ds1820总线复位保持16us MOV DQ,C ;写入一个bit MOV R4,#20 WR3:DJNZ R4,WR3 ;等待40us DJNZ R3,WR1 ;写入下一个bit SETB DQ ;重新释放ds1820总线 RET
DS18B20:CLR EA LCALL INT ;调用初使化子程序 MOV A,#0CCH LCALL WRITE ;送入跳过ROM命令 MOV A, #44H LCALL WRITE ;送入温度转换命令 LCALL INT CCH LCALL WRITE ;送入跳过ROM命令 MOV A,#0BEH LCALL WRITE ;送入读温度暂存器命令 LCALL READ MOV TEMPER_L,A ;读出温度值低字节碩ERMPER_L LCALL READ MOV TEMPER_H,A ;TEMPER_H SETB EA RET
INT: ;初始化ds1820子程序 CLR EA L0:CLR DQ ;ds1820总线为低复位电平 MOV R2,#200 L1:CLR DQ DJNZ R2,L1 ;总线复位电平保持400us SETB DQ ;释放ds1820总线 MOV R2,#30 L4:DJNZ R2,L4 ;释放ds1820总线保持60us CLR C ;清存在信号 ORL C,DQ JC L0 ;存在吗?不存在则重新来 MOV R6,#80 L5:ORL C,DQ JC L3 DJNZ R6,L5 SJMP L0 L3:MOV R2,#240 L2:DJNZ R2,L2
DS18B20智能温度控制器(附软件程序)
DS18B20智能温度控制器DALLAS最新单线数字温度传感器DS18B20简介新的“一线器件”体积更小、适用电压更宽、更经济 Dallas 半导体公司的数字化温度传感器DS1820是世界上第一片支持“一线总线”接口的温度传感器。
一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。
DS18B20、 DS1822 “一线总线”数字化温度传感器同DS1820一样,DS18B20也支持“一线总线”接口,测量温度范围为 -55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。
DS1822的精度较差为± 2°C 。
现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。
适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。
与前一代产品不同,新的产品支持3V~5.5V 的电压范围,使系统设计更灵活、方便。
而且新一代产品更便宜,体积更小。
DS18B20、 DS1822 的特性 DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。
可选更小的封装方式,更宽的电压适用范围。
分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。
DS18B20的性能是新一代产品中最好的!性能价格比也非常出色! DS1822与 DS18B20软件兼容,是DS18B20的简化版本。
省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。
继“一线总线”的早期产品后,DS1820开辟了温度传感器技术的新概念。
DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。
DS18B20的内部结构DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
温度传感器DS18B20检测程序说明
DS18B20美国达拉斯公司生产的单总线协议的数字温度检测芯片,数据的写入与读取都在一根总线上进行操作,在总线上可以连接多个DS18B20,因为每个DS18B20都有唯一的光刻ROM序列号,所以可以进行ROM匹配,搜索指令进行选择相应的从机序列号。
编写DS18B20的检测程序主要包括:初始化函数(复位脉冲+存在脉冲),写数据函数,读取数据的函数。
对DS18B20的操作包括:初始化函数,ROM指令,RAM指令这三个部分。
接下来我先说一下这三个部分所对应的时序图的理解吧。
初始化:由于上拉电阻的存在,总线默认状态是高电平,接着主机将总线拉低,维持480us 到960us的时间,再接着就是释放总线,维持时间为15us到60us,接着就由从机发出一个低电平信号,将总线拉低,表示该DS18B20是正常地,或者说是存在的,其维持时间为60us 到240us。
上面一图是写入数据的时序图。
写时序:默认状态为高电平,先将总线拉低,至少维持1us 的延时时间,接着就往总线上进行写数据操作,接着DS18B20就开始采样数据了,整个过程时间为60us到120us。
下面一图是读取数据的时序图。
读时序:默认状态为高电平,先将总线拉低,接着在15us 之前,主机进行数据采样,其维持时间也为60us到120us。
下面是我在理解了DS18B20的原理之后所写的程序,调试成功了,且能实时读取外界温度的功能,这里是不读取小数部分的温度,只读取温度的正数值。
#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};sbit DQ=P2^2;sbit duan=P2^6;sbit wei=P2^7;//是在11.0592M赫兹的频率下void delay_ms(uint t){uint i;for(;t>0;t--)for(i=110;i>0;i--);} //约为tms的延时程序void delay(uint x){while(x--);}void init_ds18b20(){uchar n;DQ=1;delay(2); //约为38usDQ=0;delay(80); //约为800usDQ=1;delay(4); //约为58usn=DQ;delay(10); //约为110us}void write_byte(uchar dat){uchar i;for(i=0;i<8;i++){DQ=0; //无论是写0或写1都要有至少1us的低电平DQ=dat&0x01;//总线直接等于写入的数据(低位在前,高位在后)delay(4); //约为58usDQ=1; //释放总线,为下一步的数据变换做准备dat>>=1;//数据进行移位操作}delay(4);}uchar read_byte(){uchar i,value;for(i=0;i<8;i++){DQ=0;value>>=1; //移位7次DQ=1; //先要释放总线,那样才能采样到有效数据if(DQ) //判断8次{value|=0x80;}delay(6); //约为78us}return value;}uchar read_temperature(){uchar a,b;init_ds18b20(); //每次操作指令前,都必须进行初始化设置write_byte(0xcc);//跳过ROM指令write_byte(0x44);//进行温度转换处理delay(300);//进行一定地延时约为3ms左右init_ds18b20();write_byte(0xcc);//跳过ROM操作write_byte(0xbe);//读取温度a=read_byte();//温度低字节b=read_byte();//温度高字节b<<=4;//b左移四位,低四位为0000b=b+(a&0xf0)>>4;//将a的低四位屏蔽,不取小数点,进行右移四位,合并成一个字节的数据return b;}void display(uchar aa,uchar bb) {duan=1;P0=table[aa];duan=0;P0=0xff;wei=1;P0=0xfe;wei=0;delay_ms(5);duan=1;P0=table[bb];duan=0;P0=0xff;wei=1;P0=0xfd;wei=0;delay_ms(5);}void main(){uchar num,shi,ge;while(1){num=read_temperature();shi=num/10; //分离出十位ge=num%10; //分离出个位display(shi,ge);}}。
1我的ds18b20总结
我的ds18b20总结,一、初始化,如图一:数据线拉低至少480us后再将其拉高,大约等待15~60us,就会收到60~240us的低电平的存在脉冲,其后数据线会恢复被拉高状态,在数据线被拉高到初始化结束经过的时间至少为480us,以下是我根据对初始化时序写的子程序,用的是51:#include <reg52.h>#define uchar unsigned char#define uint unsigned intvoid delay1(uint z)//延时子程序{ uint x,y;for(x=10;x>0;x--) /*z=1时,延时子程序用时约为61.5US*/{for(y=z;y>0;y--);}}void reset(){ uint i;DQ=1;i++;DQ=0;delay1(120);//软件仿真测试为495usDQ=1;for(i=65;i>0;i--){ //i这个数值可以改,for语句只是作为收到存在脉冲时的延时只要满足>60us就可以if(!DQ)break; //当收到存在脉冲时跳出循环}delay1(120); //大于480us}其实这个子程序并没考虑到干扰,因为假设在初始化过程有低电平脉冲的干扰,那么即使ds18b20没有发送低电平,也会认为初始化成功。
二、写时隙(1)写1时隙,如上右图:主控器将数据线拉低至少1us,并在拉低后的15us内再将其拉高,整个过程大于60us,子程序如下uchar bit1_write18b20(){uint i=0;DQ=1;i++;DQ=0;for(i=0;i<1;i++); //for(i=0;i<1;i++)约为12.94usDQ=1;for(i=0;i<4;i++); //约为51us,整个过程大于60usreturn(DQ);}(2)写0时隙,如上左图,主控器将数据线拉低至少60us后将其拉高,子程序如下:uchar bit0_write18b20(){uint i=0;DQ=1;i++;DQ=0;for(i=0;i<5;i++);//大于60usreturn(DQ);}三、读时隙阴影部分表示数据线的在这个时间段状态不确定,整个时序图的意思是主控制器将数据线拉高至少1us后,再将其拉低,在拉低后15us内的数据有效,整个时隙时间要大于60us.虽然pdf中,用两个时序图分别表示读0时隙和读1时隙,实际上读一位数的子程序只要一个,数据线拉低后1us,将数据线拉高,在15us内储存数据,再延时,使其满足总时间大于60us,下面给个例子:uchar bit_read18b20(void){ uint i;uint k;DQ=1;k++;DQ=0;for(i=0;i<1;i++); /*for(i=0;i<1;i++)约为12.94us*/DQ=1; /*60us*/return(DQ);}四、写、读一个字节数子程序:/*写一字节数*/void byte_write18b20(uint w){ uint i=0;bit b;for(;i<8;i++){ b=w&0x01;if(b)bit1_write18b20();else bit0_write18b20();w=w>>1;}}/*读一字节*/uchar byte_read18b20(void){uchar i;uint k;uchar value=0;for(i=0;i<8;i++){if(bit_read18b20())value|=(0x01<<i);for(k=0;k<6;k++); //延时使其满足读时隙时间}return(value);}(1)unsigned int Readtemp() //温度转换{unsigned char a=0;unsigned char b=0;unsigned int t=0;float tt=0;reset();byte_write18b20(0xCC);byte_write18b20(0x44);reset();byte_write18b20(0xCC); //skip rom指令byte_write18b20(0xBE); //温度转换指令a=byte_read18b20(); //连续读两个字节数据//读低8位b=byte_read18b20(); //读高8位t=b; //数值处理t<<=8;t=t|a; //两字节合成一个整型变量。
DS18B20工作过程及时序
DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。
高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。
初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。
初始时,计数器1预置的是与-55℃DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。
高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。
初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。
初始时,计数器1预置的是与-55℃相对应的一个预置值。
以后计数器1每一个循环的预置数都由斜率累加器提供。
为了补偿振荡器温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。
计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1℃计数器所需要的计数个数。
DS18B20内部的比较器以四舍五入的量化方式确定温度寄存器的最低有效位。
在计数器2停止计数后,比较器将计数器1中的计数剩余值转换为温度值后与0.25℃进行比较,若低于0.25℃,温度寄存器的最低位就置0;若高于0.25℃,最低位就置1;若高于0.75℃时,温度寄存器的最低位就进位然后置0。
这样,经过比较后所得的温度寄存器的值就是最终读取的温度值了,其最后位代表0.5℃,四舍五入最大量化误差为±,即0.25℃。
温度寄存器中的温度值以9位数据格式表示,最高位为符号位,其余8位以二进制补码形式表示温度值。
测温结束时,这9位数据转存到暂存存储器的前两个字节中,符号位占用第一字节,8位温度数据占据第二字节。
温度传感器ds18b20实验报告
温度传感器ds18b20实验报告温度传感器DS18B20实验报告引言:温度传感器是一种用于测量环境温度的设备,它在许多领域都有广泛的应用,如气象学、工业控制、冷链物流等。
本实验报告将介绍DS18B20温度传感器的原理、实验装置和实验结果,并对其性能进行评估。
一、实验原理DS18B20温度传感器是一种数字温度传感器,采用单总线接口进行通信。
它采用了最新的数字温度传感器技术,具有高精度、低功耗、抗干扰等特点。
其工作原理是利用温度对半导体材料电阻值的影响,通过测量电阻值的变化来确定温度。
二、实验装置本实验使用的实验装置包括DS18B20温度传感器、Arduino开发板、杜邦线和计算机。
Arduino开发板用于读取传感器的温度数据,并通过串口将数据传输到计算机上进行处理和显示。
三、实验步骤1. 连接电路:将DS18B20温度传感器的VCC引脚连接到Arduino开发板的5V 引脚,GND引脚连接到GND引脚,DQ引脚连接到Arduino开发板的数字引脚2。
2. 编写代码:使用Arduino开发环境编写代码,通过OneWire库和DallasTemperature库读取DS18B20传感器的温度数据。
3. 上传代码:将编写好的代码上传到Arduino开发板上。
4. 监测温度:打开串口监视器,可以看到DS18B20传感器实时的温度数据。
四、实验结果在实验过程中,我们将DS18B20温度传感器放置在不同的环境中,记录了其测得的温度数据。
实验结果显示,DS18B20温度传感器具有较高的精度和稳定性,能够准确地测量环境温度。
五、实验评估本实验评估了DS18B20温度传感器的性能,包括精度、响应时间和抗干扰能力。
实验结果表明,DS18B20温度传感器具有较高的精度,能够在0.5℃的误差范围内测量温度。
响应时间较快,能够在毫秒级别内完成温度测量。
同时,DS18B20温度传感器具有较好的抗干扰能力,能够在干扰环境下保持稳定的测量结果。
ds18b20详解及程序
ds18b20详解及程序最近都在学习和写单⽚机的程序, 今天有空⼜模仿DS18B20温度测量显⽰实验写了⼀个与DS18B20基于单总线通信的程序. DS18B20 数字温度传感器(参考:智能温度传感器DS18B20的原理与应⽤)是DALLAS 公司⽣产的1-Wire,即单总线器件,具有线路简单,体积⼩的特点。
因此⽤它来组成⼀个测温系统,具有线路简单,在⼀根通信线,可以挂很多这样的数字温度计。
DS18B20 产品的特点:(1)、只要求⼀个I/O ⼝即可实现通信。
(2)、在DS18B20 中的每个器件上都有独⼀⽆⼆的序列号。
(3)、实际应⽤中不需要外部任何元器件即可实现测温。
(4)、测量温度范围在-55 到+125℃之间; 在-10 ~ +85℃范围内误差为±5℃; (5)、数字温度计的分辨率⽤户可以从9 位到12 位选择。
将12位的温度值转换为数字量所需时间不超过750ms;(6)、内部有温度上、下限告警设置。
DS18B20引脚分布图DS18B20 详细引脚功能描述:1、GND 地信号;2、DQ数据输⼊出引脚。
开漏单总线接⼝引脚。
当被⽤在寄⽣电源下,此引脚可以向器件提供电源;漏极开路, 常太下⾼电平.通常要求外接⼀个约5kΩ的上拉电阻.3、VDD可选择的VDD 引脚。
电压范围:3~5.5V; 当⼯作于寄⽣电源时,此引脚必须接地。
DS18B20存储器结构图暂存储器的头两个字节为测得温度信息的低位和⾼位字节;第3, 4字节是TH和TL的易失性拷贝, 在每次电复位时都会被刷新;第5字节是配置寄存器的易失性拷贝, 同样在电复位时被刷新;第9字节是前⾯8个字节的CRC检验值.配置寄存器的命令内容如下:MSB LSBR0和R1是温度值分辨率位, 按下表进⾏配置.默认出⼚设置是R1R0 = 11, 即12位.温度值分辨率配置表4种分辨率对应的温度分辨率为0.5℃, 0.25℃, 0.125℃, 0.0625℃(即最低⼀位代表的温度值)12位分辨率时的两个温度字节的具体格式如下:⾼字节:其中⾼字节前5位都是符号位S, 若分辨率低于12位时, 相应地使最低为0, 如: 当分辨率为10位时, 低字节为:, ⾼字节不变....由上表可看出, 当输出是负温度时, 使⽤补码表⽰, ⽅便计算机运算(若是⽤C语⾔, 直接将结果赋值给⼀个int变量即可).DS18B20 的使⽤⽅法:由于DS18B20 采⽤的是1-Wire 总线协议⽅式,即在⼀根数据线实现数据的双向传输,⽽对单⽚机来说,我们必须采⽤软件的⽅法来模拟单总线的协议时序来完成对DS18B20芯⽚的访问。
ds18b20程序设计傻瓜式讲解
ds18b20程序设计傻瓜式讲解
DS18B20 是一款数字温度传感器,可以直接读出被测温度,并采用 9 位数字量串行输出。
下面是一个简单的 DS18B20 程序设计讲解:
1. 初始化
在 DS18B20 通信过程中,首先需要初始化数据线,即将其置为高电平。
在初始化时,需要持续至少 480 微秒的高电平。
2. 跳过 ROM
在 DS18B20 中,每个传感器都有一个唯一的 ROM 序列号,可以通过跳过ROM 操作来避免对 ROM 进行操作。
具体操作是先发出一个低电平,然后持续至少 60 微秒的高电平。
3. 发送命令
在跳过 ROM 后,需要向传感器发送命令。
常用的命令有温度转换命令和读取温度命令。
温度转换命令是 0x44,读取温度命令是 0xBE。
4. 读取数据
在发送命令后,需要等待传感器响应。
传感器响应的标志是数据线上的低电平。
在低电平持续约 60-240 微秒后,数据线将变为高电平,此时可以开始读取数据。
每次读取一位数据后,需要将数据线置为低电平,等待传感器响应。
5. 数据解析
DS18B20 的数据由 9 位数字量组成,其中最高位是符号位。
如果最高位为0,则表示温度为正数;如果最高位为 1,则表示温度为负数。
其余 8 位为温度值,可以通过一定的计算公式将其转换为实际温度值。
以上就是 DS18B20 的程序设计流程。
需要注意的是,在实际应用中,还需要考虑数据传输的校验、错误处理等问题。
(完整word版)DS18B20水温控制系统+电路图程序
水温控制系统摘要:该水温控制系统采用单片机进行温度实时采集与控制。
温度信号由“一线总线”数字化温度传感器DS18B20提供,DS18B20在-10~+85°C范围内,固有测温分辨率为0.5 ℃。
水温实时控制采用继电器控制电热丝和风扇进行升温、降温控制.系统具备较高的测量精度和控制精度,能完成升温和降温控制。
关键字:AT89C51 DS18B20 水温控制Abstract: This water temperature control system uses the Single Chip Microcomputer to carry on temperature real-time gathering and controling。
DS18B20,digitized temperature sensor, provides the temperature signal by "a main line”. In -10~+85℃the scope,DS18B20’s inherent measuring accuracy is 0.5 ℃. The water temperature real-time control system uses the electricity nichrome wire carring on temperature increiseament and operates the electric fan to realize the temperature decrease control。
The system has the higher measuring accuracy and the control precision,it also can complete the elevation of temperature and the temperature decrease control. Key Words:AT89C51 DS18B20 Water temperature control目录1.系统方案选择和论证 (2)1。
DS18B20汇编程序(完整版)
DS18B20汇编程序(完整版)DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF &_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSC CBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us ;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
DS18B20数字温度计的主程序
主程序ORG 0000HLJMP STARTSTART: MOV DISBUF4,#00H ;开始,初始化MOV DISBUF5, #00HMAIN: ;主程序LCAAL KEY ;调按键预置数子程序CLR RS1CLR RS0LCALL RESET ;调复位子程序MOV A,#0CCH ;跳过ROM匹配------0CCLCALL WRITE ;调DS18B20子程序MOV A,#44H ;发出温度转换命令LCALL WRITE ;调DS18B20子程序LCALL RESET ;调复位子程序MOV A,#0CCH ;跳过ROM匹配LCALL WRITE ;调DS18B20子程序MOV A,#0BEH ;发出读取温度值命令LCALL WRITE ;调DS18B20子程序LCALL READ ;调DS18B20子程序MOV A, 3DHMOV 29H,ALCALL READMOV A, 3DHMOV 28H,AMOV R0, #34HMOV A, 28HRLC AMOV 47H,CJNB 47H, BTOD1 ;28H中的最高位是不是为1(温度<0);小于0的温度值不处置,大于0顺序执行BTOD1: MOV A, 28HRRC AMOV 40H,CRRC AMOV 41H,CRRC AMOV 42H,CRRC AMOV 43H,CMOV A, 29HMOV 27H, AMOV C,40H ;将28H中的最低位移入C,40H41H42H43H ;为28H中的位地址RRC A ;将28H中的低4位移到A的高4位MOV C, 41HRRC AMOV C, 42HRRC AMOV C, 43HRRC AMOV 29H,A ;将28H中的低4位放入29H中MOV A, 29H ;将29H中的十六进制数转换成10进制MOV B, #100DIV ABMOV @R0, A ;百位存于34HMOV @R0, #11H ;百位不显示DEC R0MOV A, #10XCH A, BDIV ABMOV @R0, A ;十位存于33HDEC R0MOV @R0, B ;个位存于32HDEC R0ANL 27H, #0FH ;小数点后一名进制转换MOV A, 27HMOV B, #06HMUL ABMOV B, #10DIV ABMOV @R0, A ;小数点后一名存于31HMOV DISBUF0,33H ;十位MOV DISBUF1,32H ;个位MOV DISBUF2,31H ;小数位MOV DISBUF3, #0H ;置0MOV DISBUF6, #0HMOV DISBUF7, #0HLCALL CMP ;调比较报警子程序LCALL DISPLAY ;调显示子程序LJMP MAIN ;转到MAINDS18B20复位子程序RESET: NOPL0: CLR ;拉低数据线MOV R2,#200 ;发出600us的复位脉冲L1: NOPDJNZ R2, L1SETB ;主机释放数据线MOV R2,#30 ;DS18B20等待60usL4: DJNZ R2, L4CLR CORL C, ;DS18B20数据变低(存在脉冲)吗?JC L3 ;DS18B20未预备好,从头初始化MOV R6, #80L5: ORL C,JC L3 ;DS18B20数据变高,初始化成功DJNZ R6,L5 ;数据线低电平可持续3us*80=240us SJMP L0 ;初始化失败,从头初始化L3: MOV R2, #250L2: DJNZ R2,L2 ;DS18B20应答500usRET读DS18B20子程序READ: MOV R6,#8 ;循环8次,读一个字节RE1: CLRMOV R4, #6NOPNOPSETBRE2: DJNZ R4,RE2 ;等待8USMOV C, ;读DS18B20的数据RRC A ;读取的数据移入AMOV R5, #30DJNZ R6,RE1 ;读完一个字节的数据MOV 3DH,A ;数据存入3DH中SETB ;把数据线拉高RET写DS18B20子程序;写DS18B20的子程序, 从DS18B20中写出一个字节的数据WRITE: MOV R3,#8 ;循环8次,写一个字节WR1: SETB ;拉高数据线MOV R4, #8RRC A ;写入位从A中移到CYCLRWR2: DJNZ R4,WR2 ;等待16USMOV ,C ;命令字按位依次送给DS18B20MOV R4, #20WR3: DJNZ R4,WR3 ;保证写进程持续40USDJNZ R3,WR1 ;未写完一个字节转WR1继续SETB ;写完一个字节,数据线置高RET比较报警子程序CMP: MOV A,DISBUF0 ;实际测量温度值放在DISBUF8中SWAP AMOV DISBUF8, AMOV A, DISBUF1ORL A, DISBUF8MOV DISBUF8, AMOV A,DISBUF4 ;预置温度值放在DISBUF9中SWAP AMOV DISBUF9, AMOV A, DISBUF5ORL A, DISBUF9MOV DISBUF9, ACLR CMOV A, DISBUF8SUBB A, DISBUF9JNC KK ;没有借位,即实际温度值大于;预置温度值转KKCLR ;有借位,即实际温度值小于预置温度值;置0,不发报警信号RETKK: SETB ;置1,即发出报警标志发光二极管亮RET按键子程序KEY: JNB , YZBWJNB , YZSWLJMP KEYRET YZBW: LCALL DELAY1JB , KEYRETJNB , $INC DISBUF5MOV A, DISBUF4CJNE A, #10,KEYRETMOV DISBUF4, #0LJMP KEYRETYZSW: LCALL DELAY1JB , KEYRETJNB , $INC DISBUF5MOV A, DISBUF5CJNE A, #10,KEYRETMOV DISBUF5, #0 KEYRET: RET显示子程序DISPLAY: MOV A, DISBUF0MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000001BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF1MOV DPTR, #SEGMOVC A, @A+DPTRORL A, #80HMOV P1, AMOV P2, #00000010BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF2MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000100BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF3MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00001000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF4MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00010000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF5MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00100000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF6MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF7MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000000BLCALL DELAY1MOV P2, #00000000BRET; (00) (01) (02) (03) (04)SEG: DB 03FH, 06H, 05BH, 04FH, 066H ; (05) (06) (07) (08) (09)DB 06DH, 07DH, 007H, 07FH, 06FH ;延时子程序DELAY1: MOV R1, #0A0HDEL11: NOPDJNZ R1, DEL11RETEND;工作内存概念:DISBUF0 EQU 10H DISBUF1 EQU 11H DISBUF2 EQU DISBUF1+1 DISBUF3 EQU DISBUF2+1 DISBUF4 EQU DISBUF3+1 DISBUF5 EQU DISBUF4+1 DISBUF6 EQU DISBUF5+1 DISBUF7 EQU DISBUF6+1 DISBUF8 EQU DISBUF7+1 DISBUF9 EQU DISBUF8+1。
DS18B20温度传感器详解带c程序
00A2H
+0.5
0000 0000 0000 000
0000H
-0.5
1111 1111 1111 1000
FFF8H
-10.125
1111 1111 0110 1110
FF5EH
-25.0625
1111 1110 0110 1111
FF6FH
-55 执行序列与介绍 3.1 执行序列
duan=1; switch(i) {
case 0: if(zf==0) P1=numfh[zf];
else if(bai!=0) P1=numd[bai]; else if(shi!=0) P1=numd[shi]; else P1=numdg[ge]; break;
case 1: if(zf==0&&shi!=0) P1=numd[shi];
表 3.2 DS18B20 温度/数字对应关系表
温度(℃)
输出的二进制码
对应的十六进制码
+125
0000 0111 1101 0000
07D0H
+85
0000 0101 0101 0000
0550H
+25.0625
0000 0001 1001 0001
0191H
+10.125
0000 0000 1010 0010
uchar x,y; for(x=z;x>0;x--)
for(y=110;y>0;y--); } /******************15us 延时函数****************/ void delay(uint z) {
while(z--); } /******************初始化 DS18B20 函数****************/ void reset_ds18b20() {
ds18b20程序设计
ds18b20程序设计如何使用ds18b20编写程序设计。
DS18B20是一种数字温度传感器,它可以通过编程来读取环境温度信息。
本文将详细介绍如何使用DS18B20进行程序设计,以帮助读者了解如何在自己的项目中应用这款传感器。
第一步:准备工作在开始实际的程序设计之前,我们需要准备一些硬件和软件工具。
首先,我们需要一块支持DS18B20的硬件平台,例如Arduino、树莓派或其他微控制器。
其次,我们需要一块DS18B20传感器和一些杜邦线用于连接。
最后,我们需要一个编程环境,例如Arduino IDE或树莓派的Python开发环境。
第二步:连接硬件将DS18B20传感器与硬件平台连接起来是第二个关键步骤。
DS18B20传感器有三个引脚,其中一个是地线(GND),一个是电源(VCC),还有一个是数据线(DATA)。
将GND引脚连接到硬件平台的地线引脚,将VCC 引脚连接到硬件平台的电源引脚,将DATA引脚连接到硬件平台的数字引脚。
确保连接正确后,我们可以进入下一步。
第三步:配置硬件平台在编程之前,我们需要配置硬件平台,以便能够与DS18B20传感器进行通信。
具体配置的方式取决于使用的硬件平台。
在Arduino中,我们可以使用OneWire库来与DS18B20传感器进行通信。
在树莓派中,我们需要通过GPIO引脚来与传感器进行通信。
了解所使用硬件平台的配置方式是非常重要的。
第四步:编写程序一旦硬件平台配置完成,我们可以开始编写程序。
程序的目标是读取DS18B20传感器的温度数据并将其显示出来。
以下是使用Arduino IDE 编写的简单示例代码:#include <OneWire.h>#include <DallasTemperature.h>数据线引脚连接到Arduino的数字引脚2#define ONE_WIRE_BUS 2OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);void setup() {Serial.begin(9600);sensors.begin();}void loop() {sensors.requestTemperatures();float temperature = sensors.getTempCByIndex(0);Serial.print("Temperature: ");Serial.println(temperature);delay(1000);}上述代码首先引入了两个库:OneWire和DallasTemperature。
DS18B20读写时序分析
新手在DS18B20读写过程中要犯很多错误。
老衲普度众生,简要说明它怎么用。
1、过程1、2是初始化过程,每次读取都要初始化,否则18b20处于待机状态,无法成功读取。
过程1:拉低信号线480-700us,使它复位,然后释放总线15-60us,18b20会拉低总线60-240us,然后它释放总线。
所以初始化成功的一个标志就是能否读到18b20这个先低后高的操作时序。
(注意:黑色部分表示主机操作,蓝色部分表示18b20操作,每次主机操作完成之后等待18b20状态时,必须要释放总线,比如将IO设置为高阻态什么的。
否则18B20没法把状态写到线上)2、过程3、4是写1bit数据过程。
过程3是写0 ,过程4是写1。
过程3:拉低总线60us,然后抬高总线5us,完成。
过程4:拉低总线5us,然后抬高总线60us,完成3、过程5、6是读1bit过程。
过程5是读0,过程6是读1。
过程5、6:拉低总线5us,然后释放总线,读取总线,如果为0,则读入0,如果为1,则读入1。
DS18B20时序Author:exploer初始化序列——复位和存在脉冲DS18B20的所有通信都由由复位脉冲组成的初始化序列开始。
该初始化序列由主机发出,后跟由DS18B20发出的存在脉冲(presence pulse)。
下图(插图13,即如下截图)阐述了这一点。
当发出应答复位脉冲的存在脉冲后,DS18B20通知主机它在总线上并且准备好操作了。
在初始化步骤中,总线上的主机通过拉低单总线至少480μs来产生复位脉冲。
然后总线主机释放总线并进入接收模式。
当总线释放后,5kΩ的上拉电阻把单总线上的电平拉回高电平。
当DS18B20检测到上升沿后等待15到60us,然后以拉低总线60-240us的方式发出存在脉冲。
如文档所述,主机将总线拉低最短480us,之后释放总线。
由于5kΩ上拉电阻的作用,总线恢复到高电平。
DS18B20检测到上升沿后等待15到60us,发出存在脉冲:拉低总线60-240us。
数字温度传感器DS18B20报告
DS18B20报告一、DS18B20介绍DS18B20为单总线全双工通信的数字是温度传感器,其温度可以直接转换为9、10、11或12位,具体的位数由使用者通过程序写入指令改变,芯片默认的位数为12位。
芯片的形状如图。
芯片在电路的连接如图:二、读写时序1、复位时序(1)、单片机拉低总线480us~950us,然后释放总线(拉高电平)(2)、这时DS18B20会拉低信号,大约60~240us表示应答(3)、DS18B20拉低电平的60~240us之间,单片机读取总线的电平,如果是低电平,表示复位成功,否则不成功(此时一般要重负操作,直到成功为止,编程是要进行判断)(4)、DS18B20拉低电平60~240us之后,会释放总线。
2.写数据操作(1)、单片机拉低电平大约10~15us.(2)、加入要写入的时高电平,要将电平拉高,否则拉低电平。
此时要维持20~45us的时间(3)、释放总线写‘1’操作时序写‘0’操作时序3、读操作时序(1)、单片机拉低电平大约1us(2)、单片机释放总线,然后读取总线电平(3)、这时候DS18B20如果相应位是’1’会拉高电平,反之会拉低电平(4)、读取电平过后延迟大约40~45us读‘1’操作时序读‘0’操作时序三、温度读取函数步骤DS18B20开始转换:1.DS18B20复位2.写入跳过ROM的字节命令,0XCC.3.写入开始转换的功能命令,0X44.4.延迟大约750~900毫秒DS18B20读暂存数据1.DS18B20复位。
2.写入跳过ROM的字节命令,0XCC.3.写入读暂存功能命令,0XBE.4.读入第0个字节LS Byte,转换结果的低八位。
5.读入第1个字节MS Byte,转换结果的高八位。
6.DS18B20复位,表示读取暂存结束。
程序流程图:。
DS18B20学习总结
Temp = dat×0.0625;
Temp = temp×10 +0.5 ;//得到最终的温度值
Return temp;
}
9
在我们对温度值进行处理之前,我们必须在之前运行一下温度转换函数。函数如下:
Void DS18B20_TEMPCHARGE()
{
DS18B20_RESET();
While(DAT) ; //DS18B20拉低总线,则表示响应。
Delay(30); //延时必须大于最大值240us,保证能够使总线变高。
If(DAT)
ComSendStr(“Reset DS18B20 OK!”);
}
5
我们从PDF资料中,可以看到DS18B20的操作顺序。就是,我们需要先将温度计复位,然后执行一个ROM操作指令之后,才可以使用RAM操作指令或者是存储器操作指令。最后是数据操作指令。
Void delayus(unsigned char us){
While(us--) ;
}
对于这个函数,我们使用放在程序中,debug一下程序,找到这个程序在汇编语言中的实现,我们可以看到如下的汇编指令:
图中可以看出,先是给程序的寄存器R7赋值为1,然后跳转指令跳转到函数实现处,就是代码的874行,我们跟踪过去,看看代码。
下面是一张比较全面的对应表:
对于DS18B20的所有数据,都是低位在先,高位在后。无论是字节还是位,无论是读取还是写入。都是这个样子。需要注意。后面程序中就会见到。
3
DS19B20有9个字节的高速暂存器。这些RAM中保存着转换完成的温度数值和DS18B20的配置控制寄存器。字节的地址和分布如下图所示。我们只需要注意前4个字节就可以了。必要的时候,也可以读出第9个字节。如果我们使用了读取RAM的指令,DS18B20会自动全部读取,所以,如果我们只想读取前面的4个,我们读取完毕之后,需要在将DS18B20给复位。
DS18B20 测温程序完全解读
硬件:51板(1)单线ds18b20接P2.2(2)使用外部电源给ds18b20供电,没有使用寄生电源奥软件:Kei uVision 2刚开始对时序把握不好,可是在论坛里没找到比较详细的解释,所以俺倒塌了这个东东,就把俺的经验贴上来,供大家参考,呵呵……如有错误请指正#include "reg52.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned intsbit ds=P2^2;sbit dula=P2^6;sbit wela=P2^7;uchar flag ;uint temp; //参数temp一定要声明为int 型uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不带小数点数字编码uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //带小数点数字编码/*延时函数*/void TempDelay (uchar us){while(us--);}void delay(uint count) //延时子函数{uint i;while(count){i=200;while(i>0)i--;count--;}}/*串口初始化,波特率9600,方式1 */void init_com(){TMOD=0x20; //设置定时器1为模式2TH1=0xfd; //装初值设定波特率TL1=0xfd;TR1=1; //启动定时器SM0=0; //串口通信模式设置SM1=1;// REN=1; //串口允许接收数据PCON=0; //波特率不倍频// SMOD=0; //波特率不倍频// EA=1; //开总中断//ES=1; //开串行中断}/*数码管的显示*/void display(uint temp){uchar bai,shi,ge;bai=temp/100;shi=temp%100/10;ge=temp%100%10;dula=0;P0=table[bai]; //显示百位dula=1; //从0到1,有个上升沿,解除锁存,显示相应段dula=0; //从1到0再次锁存wela=0;P0=0xfe;wela=1;wela=0;delay(1); //延时约2msP0=table1[shi]; //显示十位dula=1;dula=0;P0=0xfd;wela=1;wela=0;delay(1);P0=table[ge]; //显示个位dula=1;dula=0;P0=0xfb;wela=1;wela=0;delay(1);}/*****************************************时序:初始化时序、读时序、写时序。
DS18B20程序包含温度设置、报警、华氏温度和摄氏温度转换
DS18B20程序包含温度设置、报警、华氏温度和摄氏温度转换# include# includefloat flag=0;unsigned int up=30,down=20,kf=1,hfflag=1,hf;//up为报警温度上限值,down为报警温度下限值;//kf为报警温度设定标志位,kf为1,数码管显示温度值,kf=0,进入报警温度设定选项。
//hfflag为摄氏度与华氏温度转换标志位,hfflag=1,显示的为摄氏度值,hfflag=0,显示的为华氏温度值。
//hf为用来存储华氏温度。
sbit DQ = P2^0; //ds18b20 端口unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39,0 x63,0x40,0x71};//0x39,0x63用来显示摄氏度,0x40用来显示--。
unsigned char tabb[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //带有小数点的0-9. void displayset();void delayms( int x) //延时1ms函数{int m,j;for(m=1;m<=x;m++)for(j=1;j<=123;j++);}void reset()//对ds18b20进行复位{ unsigned int i;DQ = 1; //DQ复位_nop_(); //稍做延时,此为延时1ms函数DQ = 0; //单片机将DQ拉低i=70;while(i>0) i--; //根据协议要满足大于480usDQ = 1; //拉高总线i=4;while(i>0) i--;}void dswait() //等待ds18b20响应的函数{while(DQ);while(~DQ); //检测到应答脉冲}bit readone()//读取一位数据{ unsigned int i;bit b;DQ=0;i++; //根据资料,进行一次unsigned int 型数据的++,大约为8us时间,此处i++,符合协议要求至少保持1usDQ=1;i++;i++; //延时约16us, 符合协议要求的至少延时15us以上b=DQ;i=8;while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求return(b);}unsigned char readB()//读取一字节数据{unsigned int i;unsigned char j,dat=0;for(i=0;i<8;i++){j=readone();dat=(j<<7)|(dat>>1);//将每一次输出的值通过移位相或送到dat}return(dat);}void writeB(unsigned char dat)//写操作,通过次函数可以控制ds18b20进行一系列操作{unsigned int i;unsigned char j;bit b;for(j=0;j<8;j++){b= dat & 0x01;dat >>=1;if(b) //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1{DQ=0;i++;i++; //此处延时16us。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//端口输出
//产生下降沿,至少维持一微秒
//将端口设为输入,等待读取 //在 15US 之Байду номын сангаас读取数据
//延时大概 5US
if(DQ) ch=ch|0x80;
else ch=ch&0x7f;
DELAY9(8);
} return(ch);
//每两个读数据之间间隔要大于 60US //返回读到的数据
初始化时序
初始化时序步骤: 1. 主机将端口设为输出,先发送一个高电平,然后再拉低,维持 480-960US;(推荐 500-600US) 2. 主机将端口设为输入,上拉电阻此时将电平拉高,主机等待 60US-200US;(推荐 100-150US) 3. 主机读取端口数据,低电平则初始化成功;高电平表示初始化失败; 4. 读取数据完毕后,主机等待至少 400US; (推荐 450-500US) 注: 第四步很重要,读取初始化状态后,仍然延时 400US 才可以初始化完毕,否则传感器不能 正常使用; 在这里注意端口需要不停地改变方向;在主机发送时,设为输出,主机接收时,设为输出;
} 以上三段为底层基本函数;DELAY 后面的数字 DELAY1,DELAY5,DELAY9 为延时的微秒时长; DQ 设置为硬件连接的端口,DQ_OUT 为端口方向的设置;
然后就是调用函数了: 当数据线上还有一个 18B20 时,通常步骤如下: 初始化; 跳过 ROM; 温度开始转换命令; 等待温度转换完成;//当使用 18B20 默认的 12 位转换精度,用时 750MS,经检验,一般耗时比理论稍长; 初始化; 跳过 ROM; 读暂存器命令; 将温度数据低八位,高八位依次取出; 初始化;//注:最后仍然要进行初始化 结束; 对应的函数如下:
/****************读取温度命令程序***************************************/
uint TEMP_READ_18B20(){
byte dummy=0; byte TEMH=0,TEML=0; uint TEM_RESULT; dummy=INIT_18B20(); if(dummy==0){
//返回值为 1,表示失败,返回值为 0 表示成功
}
端口写数据时序
1. 主机将电平拉高,稍微延时(推荐值:2US),然后拉低电平,产生一个下降沿,表示写数据开始;低电平维持 至少 1US;(此时推荐 2US)
2. 此时,将要写的 1 或 0 放在数据线上;(从写数据第一步开始到现在,整个过程在 15US 之内完成; 3. 然后主机延时等待至少 50US;(推荐 60US) 4. 主机最后将电平拉高; 5. 每写两位数据之间的间隔要大于 1US;
DELAY9(70);
DQ_OUT=0;
//设置为输入,设为输入 15 到 60US
DELAY9(6);
//等待 18B20 响应,如果为低电平表示初始化成功,维持 60 到 240
//微秒
DQ_RETURN=DQ;
DELAY9(70);
//读完数据后,仍然延时,至少 480US
return(DQ_RETURN);
//将数据按位取出,从 LSB 到 MSB 依次送出
//电平维持 40US 以上,18B20 将在此时将数取出
} DQ=1;
}
//最后将电平重新拉高
读数据时序
1. 主机将电平拉高,稍微延时(推荐 2US),然后将电平拉低,产生一个下降沿,表示读数据;这个低电平至少 维持 1US,此处推荐 2US;
TEM_RESULT=(TEML>>3)+(TEMH<<5); //分辨率为 0.5° 舍弃后面三位数据,并且只有 11 位是温度值,高八位中的前五位是符号位;
读取为 1 时温度为负;读取为 0 时,温度为正;
WRITE_18B20(0x44); //温度开始转换命令
}
return(dummy);
//返回 0 表示成功初始化,开始转换温度
}
注:在开始转换命令和读取温度之间,若 18B20 忙于转换温度,电平为低电位; 转换完毕将电平拉高;若不想用 DELAY 等待温度转换,可读取 DQ 值,为 1 则表示转换完毕,可以开始读 取数据了;
在单片机的使用中,不要用浮点数,全部用整数代替,在数据进行移位作乘法时,一定要注意数据有没有越界, 算出来的数很容易出现错误,并且在出现浮点数时,可以将数据放大到一定的精度,然后在显示时,将小数点 移到对应的位置即可; 在数据做乘法容易越界时,一般将其赋给一个字节多的整数,作为中间变量运算,在确保数据不会越界后,再 将其赋给最后结果;
/********************温度开始转换命令程序*******************************/
byte TEMP_DETECT_18B20(){
byte dummy=2; dummy=INIT_18B20(); if(dummy==0){
//初始化
WRITE_18B20(0XCC); //跳过 ROM,不读地址,直接通讯
/***************从 18B20 取出字符*******************************/ byte READ_18B20(){
byte ch=0; byte i;
for(i=0;i<8;i++){
DQ_OUT=1; DQ=1; DELAY1(); DQ=0; DELAY1(); DQ_OUT=0; ch=ch>>1;
//初始化
WRITE_18B20(0XCC); //跳过 ROM WRITE_18B20(0xBE); //读暂存存储器的值命令 TEML=READ_18B20(); TEMH=READ_18B20(); //读温度的高 8 位和低八位 dummy=INIT_18B20(); //最后初始化,表示读取温度结束 }
单个 18B20 实现温度测试步骤(2013/5/30)
注:该文档所用程序为 FREESCALE JM60 单片机,总线时钟为 8M,若要移植到其它 MCU 上,需要将时间重新调节, 或者更改总线时钟频率的输出;
电路图
DS18B20 工作协议:初始化,存储器操作命令,处理数据;
在关于时序的编写中,for 循环中的 NOP 指令,和单独调用的 NOP 指令所用时间完全不同;NOP 占用 1/总线时 钟的时间;如 JM60 的总线时钟为 8M,则 NOP 指令一定占用 0.125US,而将 NOP 放在 FOR 循环中,由于 FOR 的判断指令,加法指令,以及转子程序等等消耗的时间很长,远远大于一个 NOP 的指令,此时,若要获得执行 代码的精确时间,最好用示波器观察,再得出最直接的结果;
注: 在写步骤中,整个过程端口方向均为输出;
这里对时序要求高,最好用示波器调整出精确的时序; /*****************向 18B20 写数据********************************/ void WRITE_18B20(unsigned char ch){
byte i; for(i=0;i<8;i++) {
/*****************18B20 的初始化程序***************************/
byte INIT_18B20() {
byte DQ_RETURN=2;
DQ_OUT=1;
//引脚设置为输出
DQ=1;
DELAY1();
//稍微延时,即可
DQ=0;
//将电平拉低至少 480uS,最大为 960US
//返回值为温度的十倍,小数点后一位
主函数中调用:
SIGNAL=TEMP_DETECT_18B20();
if(SIGNAL==0){
if(DQ)
//此时端口为 1,则表示转换完成
TEMP_RESULT=TEMP_READ_18B20();
//返回温度的十倍值
若时序错误,很有可能读出的数据位 0XFF;若温度传感器烧坏,容易读到 85°; 使用默认 12 位转换精度,分辨率为 0.0625°,此处不需要这么高的精度因此:
2. 将端口方向设为输入,必须在下降沿之后的 15US 内将端口数据读取;此处推荐端口方向设为输入后,延时 5US, 读取端口数据;
3. 读取数据完毕后,延时 60US 即可; 4. 每两个数据位之间间隔大于 1US;
注: 在这个时序内,要不断改变端口方向; 如果上拉电阻阻值合理设置,可以小于 4.7K 欧姆,利于提高时序速度; 读数据和写数据都是 8 位,从 LSB 开始发送;
TEM_RESULT=(TEML>>3)+(TEMH<<5); //分辨率为 0.5° TEM_RESULT=TEM_RESULT*5;
if((TEMH&0X80)!=0)
//最高位为 1,则为负温度
;;
// TEM_RESULT=~TEMP_RESULT+1;
//温度为负,取补码
return(TEM_RESULT); }
DQ_OUT=1; DQ=1; DELAY1(); DQ=0; DELAY1(); DELAY1();
if((ch&0x01)==1) DQ=1; else DQ=0; ch=ch>>1; DELAY9(8); DQ=1;
//端口设为输出,并给个拉低电平的下降沿 //拉低电平,并维持一微秒以上,表示要发送数据 //在 15US 内将要写的电平写在线上