当前位置:首页 > ds18b20
  • 基于Matlab的小型温度检测系统设计

    基于Matlab的小型温度检测系统设计

    1 前言 温度是表征环境的一个重要的参数。在工程领域,尤其像工程热力学等,温度检测非常普遍,对温度精确测量以便实时控制也显得尤为重要。 在控制系统中,上位机与下位机之间实现通信的方法和应用平台很多。目前,以VB和VC开发的通信软件较多,然而,这类软件虽然功能完善,但是数据采集到计算机后要进行各种处理(例如滤波,系统辨识,曲线拟合等)就显得不方便,编程比较复杂。Matlab具有强大的数据处理能力及功能丰富的工具箱,被广泛的应用于信号处理、自动控制等领域[1]。它编程语言简单易学,利用简单的命令就可以代替复杂的代码,极大地提高了开发效率。 本实验基于Matlab环境下设计了一个小型温度检测系统,下位机使用AT89S51单片机和DS18B20完成温度数据采集,上位机在Matlab环境下,调用设备控制箱serial类操作RS-232串口,用串行通信方式交换数据,进而借助Matlab对数据进行分析和处理,得到了温度随时间变化的函数解析式,同时介绍了基于Matlab环境下PC机与单片机串行通信的实时数据处理的实现方法。 2 系统总体设计   图1 系统结构图 温度检测系统的整体结构如图1所示。PC机串口与单片机USART口通过MAX232电平转换芯片相连,构成一个主从式通信系统。系统工作时,单片机对串口和DS18B20初始化,在读取温度的同时等待中断。PC机通过调用Matlab设备控制工具箱中的serial类及相关函数来创建串口设备对象,并以读写文件的方式实现对PC机串行口的访问,PC机通过Matlab向串行口发送特殊指令从而触发单片机中断系统,单片机调用中断服务例程,读取即使温度并将采集的数据通过串行口回送给PC机。此时,Matlab通过查询的方式,实时接收单片机发送的数据,并完成对数据的分析处理及图形显示。 3 下位机部分 下位机部分由AT89S51单片机和DS18B20温度传感器构成,主要负责温度数据的采集工作,并通过串行通信实时地将数据传送到上位机进行处理,PC机与MUC串口通信技术相对而言已经比较成熟。 3.1串行通信协议 串口通信协议SPCP(Serial Port Communication Protocol)设计思想是基于帧传输方式,在本实验中,设定字符格式为1个起始位,8个数据位和一个停止位,无奇偶校验,中间8位即为有效数据,波特率设置为9600,为保证数据可靠传输,在传送数据前通过握手建立连接,软件握手协议规定如下: 上位机发送握手信号0xff给下位机,下位机如果接受到上位机的信号为握手信号,则回送数据包给上位机,其中第一个数据为握手信号,以二个数据为温度传感器采集到的温度数据,此时,上位机如果接受到的第一个数据不是握手信号,则丢弃该数据包,若是,则表示握手成功,直接存储第二个数据。 3.2温度数据采集(DS18B20) 本系统中采用DALLAS生产的“一线总线”可编程数字化温度传感器DS18B20,与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯,在使用中不需要任何外围元件,设计可用数据线供电,简化系统的硬件,同时支持多点组网功能,多个DS18B20可以并联在惟一的三线上,实现多点测温,使用起来非常方便。尽管如此,DS18B20是以牺牲软件资源换取硬件资源的,由于采用单总线数据出数方式,DS18B20的数据I/O均由同一根线完成,因此,对读写的操作时序要求非常严格。 根据DTASHEET,对DS18B20的编程主要注意以下几个方面: 1,精确延时问题[2]:为了保证DS18B20的严格时序,可以将延时分为2种:10us以下的短延时和10us以上的长延时。短延时可以使用C51提供的内部函数_nop_()来实现,一个nop()函数相当于一条DJNZ汇编指令,约2us;长延时主要有15us,90us,270us,540us等,这些延时均为15us的整数倍,一次可以使用nop()函数编写一个延时15us的函数delay15(n)。 2,基本操作:DS18B20的一线工作协议流程是:初始化→ROM操作指令→存储器操作指令→数据传输。对DS18B20 进行所有的读写操作都是从初始化开始的,主要分为初始化操作,读操作和写操作。 基于以上分析,对DS18B20的编程源码如下: Init_DS18B20(void) //初始化函数 {DQ = 1; //DQ复位 Delay15(1); //稍做延时 DQ = 0; //单片机将DQ拉低 Delay15(32); //精确延时 大于 480us DQ = 1; //拉高总线 Delay15(6); //延时90us x=DQ; //读存在脉冲 delay15(20); //延时约270us } Write_DS18B20(unsigned char dat)//写一个字节 { unsigned char i="0";//定义循环变量 for (i=0; i<8; i++) { DQ = 0; //复位 DQ = dat&0x01;//取数据的第i位并送出 Delay15(1);//延时 DQ = 1; //停止 dat>>=1;//右移 } } Read_DS18B20(void)//读一个字节 { unsigned char i="0"; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; // 复位 dat>>=1; DQ = 1; // 给脉冲信号 if(DQ) dat|=0x80;//取位脉冲并存入dat delay15(1);//延时 } return(dat); } 4 上位机部分(PC) 上位机通过串口向下位机发送命令实现对下位机的控制,并实时地接受下位机传送过来的数据,对其分析处理,将结果用图形显示并存储,完成人机交互过程。 Matlab并不具备直接访问硬件的能力,但是支持面向对象技术,通过调用Instrument Control Toolbox中的serial类函数来创建串口对象,对串口对象操作就是对串口操作,使用起非常方便。同时,Matlab封装的串口对象支持对串口的异步读写操作,使得计算机在读写串口时能同时进行其他处理工作,因而能大大提高计算机执行效率。Matlab用多线程技术实现这种异步操作,通过异步读写设置,计算机在执行读写串口函数时能立即返回不必等待串口把数据传输完毕, 当指定的数据传输结束时就触发事件,执行事件回调函数,可以在事件回调函数中编程,进行数据处理,这样就不会造成因等待串口传输数据引起的时间浪费。 4.1 Matlab下串口编程 MATLAB的Instrument Control Toolbox提供了 MATLAB与仪器仪表通信的功能 ,它支持 GPIB 通用接口总线 、VISA、TCP/ IP、UDP、RS2232等多个协议 ,具有同步和异步读写功能以及事件处理和回调操作功能,可读写和记录二进制和ASCII文本数据。与串口有关的主要函数如下[3]: (1)建立串口对象函数:obj=seril(’port’,’property name’,propertyvalue……),其中主要的属性有:baudrate(波特率),databits(数据位),parity(校验方式),stopbits(终止位)等,可以在初始化时进行赋值或者使用set函数。 (2)打开串口设备对象:fopen(obj) (3) 串口读写操作:当matlab通信数据采用二进制格式时,读写串口设备的命令为fread()和fwrite();当通行数据采用文本(ASCII)格式时,读写串口设备的命令为fscanf()和fprintf()。 (4)关闭并清除设备对象: Fclose(obj);%关闭串口设备对象 Delete(obj);%删除内存中的串口设备对象 基于本系统串口通信协议,对串口对象的读写部分程序如下: Obj=serial(’com1’,’baudrate’,9600,’parity’,’none’,’databits’,8,’stopbits’,1);%初始化串口 Fopen(obj);%打开串口对象 Fwrite(obj,256);%向串口发送握手信号0xff TMP=fread(obj,3,’unit8’);%从串口读取3字节数据,后2个即是16bit温度数据 If TMP(1)= =256 %判断第一个字节受否是握手信号 For i = 1:3 Dat(i)=TMP(i+1);%剔除第一个握手信号字节 End End Fclose(obj);%关闭串口设备对象 Delete(obj);%删除内存中的串口设备对象 4.2 Matlab数据分析 单片机一般能处理简单的8位无符号数的四则运算,而DS18B20可以程序设定9~12位的分辨率,精度可达±0.5℃,温度以16bit带符号位扩展的二进制补码形式读出,如果使用单片机进行快速的实时处理则比较费力,同时单片机还要与DS18B20及上位机通信,系统资源也比较紧张。因而可以将读取的16bit温度数据直接送往PC机,由上位机来完成。Matlab强大的计算能力和绘图功能给数据分析带来了极大的方便,这不仅可以合理利用系统资源,也使得系统的通信过程更流畅。   图2所示的是用DS18B20测得的连续10个温度数据的变化曲线图。使用max()和min()函数可以求出温度的极大极小值,调用polyfit()函数还可以进行最小二乘回归分析与曲线拟合,进而求出温度变化的解析式,本实验中使用二阶拟合后,得到的温度随时间变化的函数解析式为:F(T)= 0.0125*T2 - 0.0145T+27.3083. 5 结语 Matlab是一款在控制领域应用十分广泛的软件,本实验基于Matlab环境下PC机与单片机实时通信及数据处理的方法,设计了一个小型温度检测系统,串口通信使用Matlab编程,极大的提高了开发效率,充分利用了Matlab的强大的数据分析能力,得到了温度随时间变化的函数解析式,取得了较好的效果,扩展了Matlab的使用范围,具有一定实用性。 本文作者创新观点:使用DS18B20传感器简化了硬件结构,采用Matlab编程,充分利用其数据分析能力,合理利用系统资源,提高了开发效率,扩展了Matlab的使用范围。

    时间:2019-08-28 关键词: 传感器 数据采集 ds18b20 matlab编程

  • 基于DS18B20数字温度计设计

    单片机除了可以测量电信号外,还可以用与温度、湿度等非电信号的测量,能独立工作的单片机温度检测、温度控制系统已经广泛的应用于很多领域。单片机的接口信号是数字信号,要想用单片机作区温度这类非电信号,就要使用温度传感器将温度信息转换为电流或者电压信号输出,如果转化的信号是模拟信号,还需要进行A/D转化,以满足单片机接口的需要。 本试验结合温度传感器DS18B20及单线技术实现数字温度计的设计。 主要器件: 1、 AT89C52单片机芯片,控制温度传感器和数据处理。 2、 单线数字温度传感器DS18B20。 试验流程图:   实验电路图:   试验程序代码: //DigThermo.h程序 #ifndef _DIGTHERMO_H // 防止DigThermo.h被重复引用 #define _DIGTHERMO_H #include // 引用标准库的头文件 #include #include #include #define uchar unsigned char #define uint unsigned int uchar tplsb,tpmsb; // 温度值低位、高位字节 sbit DQ = P3^5; // 数据通信线DQ #endif //DigThermo.c程序 #include "DigThermo.h" /* 延时t毫秒 */ void delay(uint t) { uint i; while(t--) { /* 对于11.0592M时钟,约延时1ms */ for (i=0;i<125;i++) {} } } /* 产生复位脉冲初始化DS18B20 */ void TxReset(void) { uint i; DQ = 0; /* 拉低约900us */ i = 100; while (i>0) i--; DQ = 1; // 产生上升沿 i = 4; while (i>0) i--; } /* 等待应答脉冲 */ void RxWait(void) { uint i; while(DQ); while(~DQ); // 检测到应答脉冲 i = 4; while (i>0) i--; } /* 读取数据的一位,满足读时隙要求 */ bit RdBit(void) { uint i; bit b; DQ = 0; i++; DQ = 1; i++;i++; // 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效 b = DQ; i = 8; while(i>0) i--; return (b); } /* 读取数据的一个字节 */ uchar RdByte(void) { uchar i,j,b; b = 0; for (i=1;i<=8;i++) { j = RdBit(); b = (j<<7)|(b>>1); } return(b); } /* 写数据的一个字节,满足写1和写0的时隙要求 */ void WrByte(uchar b) { uint i; uchar j; bit btmp; for(j=1;j<=8;j++) { btmp = b&0x01; b = b>>1; // 取下一位(由低位向高位) if (btmp) { /* 写1 */ DQ = 0; i++;i++; // 延时,使得15us以内拉高 DQ = 1; i = 8; while(i>0) i--; // 整个写1时隙不低于60us } else { /* 写0 */ DQ = 0; i = 8; while(i>0) i--; // 保持低在60us到120us之间 DQ = 1; i++; i++; } } } /* 启动温度转换 */ void convert(void) { TxReset(); // 产生复位脉冲,初始化DS18B20 RxWait(); // 等待DS18B20给出应答脉冲 delay(1); // 延时 WrByte(0xcc); // skip rom 命令 WrByte(0x44); // convert T 命令 } /* 读取温度值 */ void RdTemp(void) { TxReset(); // 产生复位脉冲,初始化DS18B20 RxWait(); // 等待DS18B20给出应答脉冲 delay(1); // 延时 WrByte(0xcc); // skip rom 命令 WrByte(0xbe); // read scratchpad 命令 tplsb = RdByte(); // 温度值低位字节(其中低4位为二进制的“小数”部分) tpmsb = RdByte(); // 高位值高位字节(其中高5位为符号位) } /* 主程序,读取的温度值最终存放在tplsb和tpmsb变量中。 tplsb其中低4位为二进制的“小数”部分;tpmsb其中高 5位为符号位。真正通过数码管输出时,需要进行到十进 制有符号实数(包括小数部分)的转换。 */ void main(void) { do { delay(1); // 延时1ms convert(); // 启动温度转换,需要750ms delay(1000); // 延时1s RdTemp(); // 读取温度 } while(1); }

    时间:2019-08-15 关键词: ds18b20 数字温度计

  • DS18B20数字温度计使用

    DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。 1、DS18B20产品的特点 (1)、只要求一个端口即可实现通信。 (2)、在DS18B20中的每个器件上都有独一无二的序列号。 (3)、实际应用中不需要外部任何元器件即可实现测温。 (4)、测量温度范围在-55。C到+125。C之间。 (5)、数字温度计的分辨率用户可以从9位到12位选择。 (6)、内部有温度上、下限告警设置。 2、DS18B20的引脚介绍 TO-92封装的DS18B20的引脚排列见图1,其引脚功能描述见表1。 (底视图) 图1   表1 DS18B20详细引脚功能描述 序号 名称 引脚功能描述 1 GND 地信号 2 DQ 数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源。 3 VDD 可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。 3. DS18B20的使用方法 由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。 由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。 DS18B20的复位时序   DS18B20的读时序 对于DS18B20的读时序分为读0时序和读1时序两个过程。 对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60us才能完成。   DS18B20的写时序 对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。 对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。   4. 实验任务 用一片DS18B20构成测温系统,测量的温度精度达到0.1度,测量的温度的范围在-20度到+100度之间,用8位数码管显示出来。 5. 电路原理图   6. 系统板上硬件连线 (1). 把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“动态数码显示”区域中的ABCDEFGH端子上。 (2). 把“单片机系统”区域中的P2.0-P2.7用8芯排线连接到“动态数码显示”区域中的S1S2S3S4S5S6S7S8端子上。 (3). 把DS18B20芯片插入“四路单总线”区域中的任一个插座中,注意电源与地信号不要接反。 (4). 把“四路单总线”区域中的对应的DQ端子连接到“单片机系统”区域中的P3.7/RD端子上。 7. C语言源程序 #include #include unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f}; unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0x00,0x40}; unsigned char code dotcode[32]={0,3,6,9,12,16,19,22, 25,28,31,34,38,41,44,48, 50,53,56,59,63,66,69,72, 75,78,81,84,88,91,94,97}; unsigned char displaycount; unsigned char displaybuf[8]={16,16,16,16,16,16,16,16}; unsigned char timecount; unsigned char readdata[8]; sbit DQ=P3^7; bit sflag; bit resetpulse(void) { unsigned char i; DQ=0; for(i=255;i>0;i--); DQ=1; for(i=60;i>0;i--); return(DQ); for(i=200;i>0;i--); } void writecommandtods18b20(unsigned char command) { unsigned char i; unsigned char j; for(i=0;i<8;i++) { if((command & 0x01)==0) { DQ=0; for(j=35;j>0;j--); DQ=1; } else { DQ=0; for(j=2;j>0;j--); DQ=1; for(j=33;j>0;j--); } command=_cror_(command,1); } } unsigned char readdatafromds18b20(void) { unsigned char i; unsigned char j; unsigned char temp; temp=0; for(i=0;i<8;i++) { temp=_cror_(temp,1); DQ=0; _nop_(); _nop_(); DQ=1; for(j=10;j>0;j--); if(DQ==1) { temp=temp | 0x80; } else { temp=temp | 0x00; } for(j=200;j>0;j--); } return(temp); } void main(void) { TMOD=0x01; TH0=(65536-4000)/256; TL0=(65536-4000)%256; ET0=1; EA=1; while(resetpulse()); writecommandtods18b20(0xcc); writecommandtods18b20(0x44); TR0=1; while(1) { ; } } void t0(void) interrupt 1 using 0 { unsigned char x; unsigned int result; TH0=(65536-4000)/256; TL0=(65536-4000)%256; if(displaycount==2) { P0=displaycode[displaybuf[displaycount]] | 0x80; } else { P0=displaycode[displaybuf[displaycount]]; } P2=displaybit[displaycount]; displaycount++; if(displaycount==8) { displaycount=0; } timecount++; if(timecount==150) { timecount=0; while(resetpulse()); writecommandtods18b20(0xcc); writecommandtods18b20(0xbe); readdata[0]=readdatafromds18b20(); readdata[1]=readdatafromds18b20(); for(x=0;x<8;x++) { displaybuf[x]=16; } sflag=0; if((readdata[1] & 0xf8)!=0x00) { sflag=1; readdata[1]=~readdata[1]; readdata[0]=~readdata[0]; result=readdata[0]+1; readdata[0]=result; if(result>255) { readdata[1]++; } } readdata[1]=readdata[1]<<4; readdata[1]=readdata[1] & 0x70; x=readdata[0]; x=x>>4; x=x & 0x0f; readdata[1]=readdata[1] | x; x=2; result=readdata[1]; while(result/10) { displaybuf[x]=result%10; result=result/10; x++; } displaybuf[x]=result; if(sflag==1) { displaybuf[x+1]=17; } x=readdata[0] & 0x0f; x=x<<1; displaybuf[0]=(dotcode[x])%10; displaybuf[1]=(dotcode[x])/10; while(resetpulse()); writecommandtods18b20(0xcc); writecommandtods18b20(0x44); } }

    时间:2019-08-07 关键词: ds18b20 数字温度计

  • 使用AT89C51和DS18B20温度测量方法

    温度的测量和控制在激光器、光纤光栅的使用及其他的工农业生产和科学研究中应用广泛。温度检测的传统方法是使用诸如热电偶、热电阻、半导体PN结之类的模拟温度传感器。信号经取样、放大后通过模数转换,再交自单片机处理。被测温度信号从温敏元件到单片机,经过众多器件,易受干扰、不易控制且精度不高。因此,本文介绍一种新型的可编程温度传感器DS18B20,他能代替模拟温度传感器和信号处理电路,直接与单片机沟通,完成温度采集和数据处理。DS18B20与AT89C51结合实现最简温度检测系统,该系统结构简单,抗干扰能力强,适合于恶劣环境下进行现场温度测量,有广泛的应用前景。 2温度测量系统硬件 系统结构图如图1所示[1]。这里通过上拉电阻直接驱动LED显示。以增加线路复杂度为代价,减少芯片数量。   2.1数字温度传感器DS18B20 DS18B20是美国DALLAS公司推出的单总线数字测温芯片。他具有独特的单总线接口方式,仅需使用1个端口就能实现与单片机的双向通讯。采用数字信号输出提高了信号抗干扰能力和温度测量精度。他的工作电压使用范围宽(3.0~5.5 V),可 以采用外部供电方式,也可以采用寄生电源方式,即当总线DQ为高电平时,窃取信号能量给DS18B20供电。他还有负压特性,电源极性接反时,DS18B20不会因接错线而烧毁,但不能正常工作。可以通过编程实现9~12位的温度转换精度设置。由表1[2]可见,设定的分辨率越高,所需要的温度数据转换时间就越长,在实际应用中要将分辨率和转换时间权衡考虑。 DS18B20采用3脚TO-92封装,形如三极管,同时也有8脚SOIC封装,还有6脚的TSOC封装。测温范围为-55~+125℃,在一10~85℃范围内,精度为±0.5℃。每一个DS18B20芯片的ROM中存放了一个64位ID号:前8位是产品类型编号,随后48位是该器件的自身序号,最后8位是前面56位的循环冗余校验码。又因其可以采用寄生电源方式供电。因此,一条总线上可以同时挂接多个DS18B20,实现多点测温系统。另外用户还可根据实际情况设定非易失性温度报警上下限值TH和TL。DS18B20检测到温度值经转换为数字量后,自动存入存储器中,并与设定值TH或TL进行比较,当测量温度超出给定范围时,就输出报警信号,并自动识别是高温超限还是低温超限。   2.2 AT89C51单片机 AT89C51单片机是ATMEL公司生产的高性能8位单片机,主要功能特性如下: ①兼容MCS-51指令系统; ②32个双向I/O口,两个16位可编程定时/计数器; ③1个串行中断,两个外部中断源; ④可直接驱动LED; ⑤低功耗空闲和掉电模式; ⑥4 kB可反复擦写(>1 000次)FLASI ROM; ⑦全静态操作O~24 MHz; ⑧128×8 b内部RAM。 该款芯片的超低功耗和良好的性能价格比使其非常适合嵌入式产品应用。 3温度测量系统软件 DS18B20简单的硬件接口是以相对复杂的接口编程为代价。由于DS18B20通过单总线与单片机进行通讯,所以其通讯功能是分时完成的。他与单片机的接口协议是通过严格的时序来实现的,只有在特定的时隙,才能实现DS18B20数据的写入和读出。这里以AT89C51和一个DS18B20通讯为例,列出部分通讯的汇编语言代码。   3.1 初始化子程序(RESET) 与DS18B20的所有通讯都是由一个单片机的复位脉冲和一个DS18B20的应答脉冲开始的。单片机先发一个复位脉冲,保持低电平时间最少480μs,最多不能超过960μs。然后,单片机释放总线,等待DS18B20的应答脉冲。DS18B20在接受到复位脉冲后等待15~60μs才发出应答脉冲。应答脉冲能保持60~240μs。单片机从发送完复位脉冲到再次控制总线至少要等待480 μs。程序代码如下:   3.2 WRITE子程序 写时隙需要15~75 μs,且在2次独立的写时隙之间至少需要1μs的恢复时间。写时隙起始于单片机拉低总线。以要把单片机A中的数据发给DS18B20为例,程序代码如下:   3.3 READ子程序 读时隙需15~60 μs,且在2次独立的读时隙之间至少需要1 μs的恢复时间。读时隙起始于单片机拉低总线至少1 μs。DSl8820在读时隙开始15μs后开始采样总线电平。以单片机读取2 B的数据为例。程序代码如下:   用DS18820测量温度,在其内部就能进行A/D转换,输出数字量与单片机直接通讯,无需外加A/D转换器,转换速度快,降低了成本,而且简化了电路,提高了系统的集成度,使其满足了最简的要求。这个温度传感器稍加改良,配合半导体制冷器还能实现高精度的温度控制功能。

    时间:2019-07-22 关键词: at89c51 温度测量 ds18b20

  • 基于DS18B20设计的多点测温系统

    1温度传感器DS18B20介绍 DALLAS公司单线数字温度传感器DS18B20是一种新的“一线器件”,它具有体积小、适用电压宽等特点。一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。DS18B20支持“一线总线”接口,测量温度范围为-55℃~+125℃,在-10℃~+85℃范围内,精度为±0.5℃;通过编程可实现9~12位的数字值读数方式;可以分别在93.75ms和750ms内将温度值转化为9位和12位的数字量。每个DS18B20具有唯一的64位长序列号,存放于DS18B20内部ROM只读存储器中。 DS18B20温度传感器的内部存储器包括1个高速暂存RAM和1个非易失性的电可擦除E2RAM,后者存放高温度和低温度触发器TH、TL和结构寄存器。暂存存储器包含了8个连续字节,前2字节为测得的温度信息,第1个字节为温度的低8位,第2个字节为温度的高8位。高8位中,前4位表示温度的正(全“0”)与负(全“1”);第3个字节和第4个字节为TH、TL的易失性拷贝;第5个字节是结构寄存器的易失性拷贝,此三个字节内容在每次上电复位时被刷新;第6、7、8个字节用于内部计算;第9个字节为冗余检验字节。所以,读取温度信息字节中的内容,可以相应地转化为对应的温度值。表1列出了温度与温度字节间的对应关系。   系统分为现场温度数据采集和上位监控PC两部分。图1为系统的结构图。需要指出的是,下位机可以脱离上位PC机而独立工作。增加上位机的目的在于能够更方便地远离现场实现监控、管理。现场温度采集部分采用8051单片机作为中央处理器,在P1.0口挂接10个DS18B20传感器,对10个点的温度进行检测。非易失性RAM用作系统温度采集及运行参数等的缓冲区。上位PC机通过RS485通信接口与现场单片微处理器通信,对系统进行全面的管理和控制,可完成数据记录,打印报表等工作。   2.1DS18B20与单片机的接口电路 DS18B20与8051单片机连接非常简单,只需将DS18B20信号线与单片机一位I/O线相连,且一位I/O线可连接多个DS18B20,以实现单点或多点温度测量。DS18B20可以通过2种方式供电:外加电源方式和寄生电源方式。前者需要外加电源,电源的正负极分别与DS18B20的VDD和GND相连接。后者采用寄生电源,将DS18B20的VDD与GND接在一起,当总线上出现高电平时,上拉电阻提供电源;当总线低电平时,内部电容供电。由于采用外加电源方式更能增强DS18B20的抗干扰性,故本设计采用这种方式。在实际应用中,传感器与单片机的距离往往在几十米到几百米,传输线的寄生电容对DS18B20的操作也有一定的影响,所以往往在接口的地方稍加改动,以增加芯片的驱动能力和减少传输线电容效应带来的影响,达到远距离传输的目的。 2.2键盘及显示 键盘通过编程设置可完成以下功能:对温度值进行标定,定时显示各路的温度值,单独显示某路的温度值,给每一路设定上下限报警值等。LED则可为用户提供直观的视觉信息。在工作现场,用户可通过6位LED的显示数据来确定系统的当前工作状态以及采样的温度值信息等。 2.3报警电路 当被测温度值超过预先设定的上下限时,报警电路作出响应,蜂鸣器发出响声,告知用户温度的异常。具体哪一个传感器温度值超限,可由软件查询各DS18B20内部告警标志而确定,继而调整该现场温度,以达到对温度波动的控制。 3.1下位机软件 系统下位测温部分软件采用MCS51汇编语言编写,主要完成对DS18B20的读写操作,实现实时数据的采集,并获取最终温度值送至单片机内存。但需要注意的是,由于DS18B20的单总线方式,数据的读写都占用同一根线,所以每一种操作都必须严格按照时序进行。图2为测温子系统流程图。单片机首先发送复位脉冲,该脉冲使信号线上所有的DS18B20芯片都被复位,接着发送ROM操作命令,使得序列号编码匹配的DS18B20被激活。被激活后的DS18B20进入接收内存访问命令状态,内存访问命令完成温度转换、读取等工作(单总线在ROM命令发送之前存储命令和控制命令不起作用)。 3.2上位机软件 系统上位机的软件采用VC++6.0编写。主要完成的功能包括:与下位单片微机的实时通信;模拟显示各采集点温度曲线;保存各测温点温度数据;统计各采集点平均温度值;打印各点温度统计报表等。     本系统具有如下特点: a.结构简单,成本低廉,维护方便。 b.直接将温度数据进行编码,可以只使用单根电缆传输温度数据,通信方便,传输距离远且抗干扰性强。 c.配置灵活、方便、易于扩展。可扩展多路下位温度采集子系统,将它们通过RS485与上位PC机组网,形成多点温度采集网络。也可在各子系统中有选择性地增减温度传感器。 d.工作稳定,测温精度高。实验表明,在长达200m的一位总线上挂接24个DS18B20温度传感器,系统可正确地进行温度采集,分辨率为0.5℃。 e.适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。在大范围温度多点监控系统中具有十分诱人的应用前景。

    时间:2019-07-22 关键词: ds18b20 多点测温系统

  • DS18B20温度单片机控制显示C程序

    温度值精确到0.1度,lcd1602显示 仿真电路图如下   c程序如下: #include #define uchar unsigned char #define uint unsigned int sbit DQ=P3^7;//ds18b20与单片机连接口 sbit RS=P3^0; sbit RW=P3^1; sbit EN=P3^2; unsigned char code str1[]={"temperature: "}; unsigned char code str2[]={" "}; uchar data disdata[5]; uint tvalue;//温度值 uchar tflag;//温度正负标志 /*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的) {unsigned int i,j; for(i=0;i for(j=0;j<100;j++); } void wr_com(unsigned char com)//写指令// { delay1ms(1); RS=0; RW=0; EN=0; P2=com; delay1ms(1); EN=1; delay1ms(1); EN=0; } void wr_dat(unsigned char dat)//写数据// { delay1ms(1);; RS=1; RW=0; EN=0; P2=dat; delay1ms(1); EN=1; delay1ms(1); EN=0; } void lcd_init()//初始化设置// {delay1ms(15); wr_com(0x38);delay1ms(5); wr_com(0x08);delay1ms(5); wr_com(0x01);delay1ms(5); wr_com(0x06);delay1ms(5); wr_com(0x0c);delay1ms(5); } void display(unsigned char *p)//显示// { while(*p!='\0') { wr_dat(*p); p++; delay1ms(1); } } init_play()//初始化显示 { lcd_init(); wr_com(0x80); display(str1); wr_com(0xc0); display(str2); } /******************************ds1820程序***************************************/ void delay_18B20(unsigned int i)//延时1微秒 { while(i--); } void ds1820rst()/*ds1820复位*/ { unsigned char x=0; DQ = 1; //DQ复位 delay_18B20(4); //延时 DQ = 0; //DQ拉低 delay_18B20(100); //精确延时大于480us DQ = 1; //拉高 delay_18B20(40); } uchar ds1820rd()/*读数据*/ { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; //给脉冲信号 dat>>=1; DQ = 1; //给脉冲信号 if(DQ) dat|=0x80; delay_18B20(10); } return(dat); } void ds1820wr(uchar wdata)/*写数据*/ {unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = wdata&0x01; delay_18B20(10); DQ = 1; wdata>>=1; } } read_temp()/*读取温度值并转换*/ {uchar a,b; ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0x44);//*启动温度转换*/ ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0xbe);//*读取温度*/ a=ds1820rd(); b=ds1820rd(); tvalue=b; tvalue<<=8; tvalue=tvalue|a; if(tvalue<0x0fff) tflag=0; else {tvalue=~tvalue+1; tflag=1; } tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数 return(tvalue); } /*******************************************************************/ void ds1820disp()//温度值显示 { uchar flagdat; disdata[0]=tvalue/1000+0x30;//百位数 disdata[1]=tvalue%1000/100+0x30;//十位数 disdata[2]=tvalue%100/10+0x30;//个位数 disdata[3]=tvalue%10+0x30;//小数位 if(tflag==0) flagdat=0x20;//正温度不显示符号 else flagdat=0x2d;//负温度显示负号:- if(disdata[0]==0x30) {disdata[0]=0x20;//如果百位为0,不显示 if(disdata[1]==0x30) {disdata[1]=0x20;//如果百位为0,十位为0也不显示 } } wr_com(0xc0); wr_dat(flagdat);//显示符号位 wr_com(0xc1); wr_dat(disdata[0]);//显示百位 wr_com(0xc2); wr_dat(disdata[1]);//显示十位 wr_com(0xc3); wr_dat(disdata[2]);//显示个位 wr_com(0xc4); wr_dat(0x2e);//显示小数点 wr_com(0xc5); wr_dat(disdata[3]);//显示小数位 } /********************主程序***********************************/ void main() { init_play();//初始化显示 while(1) {read_temp();//读取温度 ds1820disp();//显示 } }

    时间:2019-07-18 关键词: 单片机 ds18b20 控制显示

  • 51单片机——DS18B20

    DS18B20——温度传感器,单片机可以通过 1-Wire 和 DS18B20 进行通 信,最终将温度读出。1-Wire 总线的硬件接口很简单,只需要把 18B20 的数据引脚和单片 机的一个 IO 口接上就可以通信。最高12为的温度存储值,补码形式存储。 2字节,LSB低字节,MSB高字节,-55~125 1、初始化 检测存在脉冲:总线上存在DS18B20,总线会根据时序要求返回一个低电平脉冲。单片机要拉低这个引脚,持续大概 480us到960us之间 的时间即可,我们的程序中持续了 500us。然后,单片机释放总线,就是给高电平,DS18B20 等待大概 15 到 60us 后,会主动拉低这个引脚大概是 60 到 240us,而后 DS18B20 会主动释放总线,这样 IO 口会被上拉电阻自动拉高。   2、ROM操作指令 Skip ROM(跳过ROM):0xCC。当总线上只有一个器件的时候,可以跳过 ROM,不进行ROM 检测。 3、RAM存储器操作指令 Read Scratchpad(读暂存寄存器):0xBE—— DS18B20 的温度数据是 2 个字节,我们读取数据的时候,先 读取到的是低字节的低位,读完了第一个字节后,再读高字节的低位,一直到两个字节全部 读取完毕。 Convert Temperature(启动温度转换):0x44—— 12位最大的转换时间是 750ms 4、DS18B20的位写时序   当要给 DS18B20 写入‘0’的时候,单片机直接将引脚拉低,持续时间大于 60us 小于120us 就可以了。图上显示的意思是,单片机先拉低 15us 之后,DS18B20 会在从 15us 到60us 之间的时间来读取这一位,DS18B20 最早会 15us 的时刻读取,典型值是 30us 的时刻读取,最多不会超过 60us,DS18B20 必然读取完毕,所以持续时间超过 60us 即可。 当要给DS18B20 写入‘1’的时候,单片机先将这个引脚拉低,拉低时间大于 1us,然后马上释放总线,即拉高引脚,并且持续时间也要大于 60us。和写‘0’类似的是,DS18B20 会在 15 到 60us 之间来读取这个‘1’。 5、DS18B20的位读时序   单片机首先要拉低这个引脚,并且至少保持1us 的时间,然后释放引脚,释放完毕后要尽快读取。从拉低这个引脚到读取引脚状态,不能超过 15us。大家从图 16-17 可以看出来,主机采样时间,也就是 MASTER SAMPLES,是 在15us 之内必须完成的。 #include #include typedef unsigned char uchar; sbit IO_18B20 = P3 ^ 2; //DS18B20通信引脚 /* 软件延时函数,延时时间(t*10)us */ void DelayX10us(uchar t) { do { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } while (--t); } /* 复位总线,获取存在脉冲,以启动一次读写操作*/ bit Get18B20Ack() { bit ack; EA = 0; //禁止总中断 IO_18B20 = 0; //产生500us复位脉冲 DelayX10us(50); IO_18B20 = 1; DelayX10us(6); //延时60us ack = IO_18B20; //读取存在脉冲 while(!IO_18B20); //等待存在脉冲结束 EA = 1; //重新使能总中断 return ack; } /* 向DS18B20写入一个字节,dat-待写入字节 */ void Write18B20(uchar dat) { uchar mask; EA = 0; //禁止总中断 for (mask = 0x01; mask != 0; mask <<= 1) //低位在先,依次移出8个bit { IO_18B20 = 0; //产生2us低电平脉冲 _nop_(); _nop_(); if ((mask & dat) == 0) //输出该bit值 { IO_18B20 = 0; } else { IO_18B20 = 1; } DelayX10us(6); //延时60us IO_18B20 = 1; //拉高通信引脚 } EA = 1; //重新使能总中断 } /* 从DS18B20读取一个字节,返回值-读到的字节 */ uchar Read18B20() { uchar dat; uchar mask; EA = 0; //禁止总中断 for (mask = 0x01; mask != 0; mask <<= 1) //低位在先,依次采集8个bit { IO_18B20 = 0; //产生2us低电平脉冲 _nop_(); _nop_(); IO_18B20 = 1; //结束低电平脉冲,等待18B20输出数据 _nop_(); //延时2us _nop_(); if (!IO_18B20) //读取通信引脚上的值 { dat &= ~mask; } else { dat |= mask; } DelayX10us(6); //再延时60us } EA = 1; //重新使能总中断 return dat; } /* 启动一次18B20温度转换,返回值-表示是否启动成功 */ bit Start18B20() { bit ack; ack = Get18B20Ack(); //执行总线复位,并获取18B20应答 if (ack == 0) //如18B20正确应答,则启动一次转换 { Write18B20(0xCC); //跳过ROM操作 Write18B20(0x44); //启动一次温度转换 } return ~ack; //ack==0表示操作成功,所以返回值对其取反 } /* 读取DS18B20转换的温度值,返回值-表示是否读取成功 */ bit Get18B20Temp(int *temp) { bit ack; uchar LSB, MSB; //16bit温度值的低字节和高字节 ack = Get18B20Ack(); //执行总线复位,并获取18B20应答 if (ack == 0) //如18B20正确应答,则读取温度值 { Write18B20(0xCC); //跳过ROM操作 Write18B20(0xBE); //发送读命令 LSB = Read18B20(); //读温度值的低字节 MSB = Read18B20(); //读温度值的高字节 *temp = ((int)MSB << 8) + LSB; //合成为16bit整型数 } return ~ack; //ack==0表示操作应答,所以返回值为其取反值 }

    时间:2019-07-15 关键词: 51单片机 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检验值. 配置寄存器的命令内容如下: 0R1R011111 MSB LSB R0和R1是温度值分辨率位, 按下表进行配置.默认出厂设置是R1R0 = 11, 即12位. 温度值分辨率配置表 R1R0分辨率最大转换时间(ms) 009bit93.75(tconv/8) 0110bit183.50(tconv/4) 1011bit375(tconv/2) 1112bit750 (tconv) 4种分辨率对应的温度分辨率为0.5℃, 0.25℃, 0.125℃, 0.0625℃(即最低一位代表的温度值) 12位分辨率时的两个温度字节的具体格式如下: 低字节: 2^32^22^12^02^-12^-22^-32^-4 高字节: SSSSS2^62^52^4 其中高字节前5位都是符号位S, 若分辨率低于12位时, 相应地使最低为0, 如: 当分辨率为10位时, 低字节为: 2^32^22^12^02^-12^-200 , 高字节不变.... 一些温度与转换后输出的数字参照如下: 温度数字输出换成16进制 +125℃00000111 11010000 07D0H +85℃00000101 010100000550H +25.0625℃00000001 100100010191H +10.125℃00000000 1010001000A2H +0.5℃00000000 000010000008H 0℃00000000 000000000000H -0.5℃11111111 11111000FFF8H -10.125℃11111111 01011110FFE5H -25.0625℃11111110 01101111FF6FH -55℃11111100 10010000FC90H 由上表可看出, 当输出是负温度时, 使用补码表示, 方便计算机运算(若是用C语言, 直接将结果赋值给一个int变量即可). DS18B20 的使用方法: 由于DS18B20 采用的是1-Wire 总线协议方式,即在一根数据线实现数据的双向传输,而对单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。 由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。 DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。 该协议定义了几种信号的时序:初始化时序(dsInit()实现)、读时序(readByte())、写时序(writeByte())。 所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。 DS18B20与单片机连接电路图:   利用软件模拟DS18B20的单线协议和命令:主机操作DS18B20必须遵循下面的顺序 1. 初始化 单线总线上的所有操作都是从初始化开始的. 过程如下: 1)请求: 主机通过拉低单线480us以上, 产生复位脉冲, 然后释放该线, 进入Rx接收模式. 主机释放总线时, 会产生一个上升沿脉冲. DQ : 1 -> 0(480us+) -> 1 2)响应: DS18B20检测到该上升沿后, 延时15~60us, 通过拉低总线60~240us来产生应答脉冲. DQ: 1(15~60us) -> 0(60~240us) 3)接收响应: 主机接收到从机的应答脉冲后, 说明有单线器件在线. 至此, 初始化完成. DQ: 0 2. ROM操作命令 当主机检测到应答脉冲, 便可发起ROM操作命令. 共有5类ROM操作命令, 如下表 命令类型 命令字节功能 Read Rom 读ROM 33H读取激光ROM中的64位,只能用于总线上单个DS18B20器件情况, 多挂时会发生数据冲突 Match Rom匹配ROM55H此命令后跟64位ROM序列号,寻址多挂总线上的对应DS18B20.只有序列号完全匹配的DS18B20才能响应后面的内存操作命令,其他不匹配的将等待复位脉冲.可用于单挂或多挂两种情况. Skip Rom 跳过ROMCCH可无须提供64位ROM序列号即可运行内存操作命令, 只能用于单挂. Search Rom搜索ROMF0H通过一个排除法过程, 识别出总线上所有器件的ROM序列号 Alarm Search告警搜索ECH命令流程与Search Rom相同, 但DS18B20只有最近的一次温度测量时满足了告警触发条件的, 才会响应此命令. 3. 内存操作命令 在成功执行ROM操作命令后, 才可使用内存操作命令. 共有6种内存操作命令: 命令类型命令字节功能 Write Scratchpad 写暂存器4EH写暂存器中地址2~地址4的3个字节(TH,TL和配置寄存器)在发起复位脉冲之前,3个字节都必须要写. Read Scratchpad 读暂存器BEH读取暂存器内容,从字节0~一直到字节8, 共9个字节,主机可随时发起复位脉冲,停止此操作,通常我们只需读前5个字节. Copy Scratchpad 复制暂存器48H将暂存器中的内容复制进EERAM, 以便将温度告警触发字节存入非易失内存. 如果此命令后主机产生读时隙, 那么只要器件还在进行复制都会输出0, 复制完成后输出1. Convert T 温度转换44H开始温度转换操作. 若在此命令后主机产生时隙, 那么只要器件还在进行温度转换就会输出0, 转换完成后输出1. Recall E2 重调E2暂存器B8H将存储在EERAM中的温度告警触发值和配置寄存器值重新拷贝到暂存器中,此操作在DS18B20加电时自动产生. Read Power Supply 读供电方式B4H主机发起此命令后每个读数时隙内,DS18B20会发信号通知它的供电方式:0寄生电源, 1外部供电. 4. 数据处理 DS18B20要求有严格的时序来保证数据的完整性. 在单线DQ上, 有复位脉冲, 应答脉冲, 写0, 写1, 读0, 读1这6种信号类型. 除了应答脉冲外, 其它都由主机产生. 数据位的读和写是通过读、写时隙实现的. 1) 写时隙: 当主机将数据线从高电平拉至低电平时, 产生写时隙.所有写时隙都必须在60us以上, 各写时隙间必须保证1us的恢复时间. 写"1" : 主机将数据线DQ先拉低, 然后释放15us后, 将数据线DQ拉高; 写"0" : 主机将DQ拉低并至少保持60us以上. 2)读时隙: 当主机将数据线DQ从高电平拉至低电平时, 产生读时隙. 所有读时隙最短必须持续60us, 各读时隙间必须保证1us的恢复时间. 读: 主机将DQ拉低至少1us,. 此时主机马上将DQ拉高, 然后就可以延时15us后, 读取DQ即可. 源代码: (测量范围: 0 ~ 99度)   DS18B20 1 #include 2 //通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值 3 sbit wela = P2^7; //数码管位选 4 sbit dula = P2^6; //数码管段选 5 sbit ds = P2^2; 6 //0-F数码管的编码(共阴极) 7 unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66, 8 0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; 9 //0-9数码管的编码(共阴极), 带小数点 10 unsigned char code tableWidthDot[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 11 0x87, 0xff, 0xef}; 12 13 //延时函数, 例i=10,则大概延时10ms. 14 void delay(unsigned char i) 15 { 16 unsigned char j, k; 17 for(j = i; j > 0; j--) 18 { 19 for(k = 125; k > 0; k--); 20 } 21 } 22 23 //初始化DS18B20 24 //让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动 25 void dsInit() 26 { 27 //一定要使用unsigned int型, 一个i++指令的时间, 作为与DS18B20通信的小时间间隔 28 //以下都是一样使用unsigned int型 29 unsigned int i; 30 ds = 0; 31 i = 103; 32 while(i>0) i--; 33 ds = 1; 34 i = 4; 35 while(i>0) i--; 36 } 37 38 //向DS18B20读取一位数据 39 //读一位, 让DS18B20一小周期低电平, 然后两小周期高电平, 40 //之后DS18B20则会输出持续一段时间的一位数据 41 bit readBit() 42 { 43 unsigned int i; 44 bit b; 45 ds = 0; 46 i++; 47 ds = 1; 48 i++; i++; 49 b = ds; 50 i = 8; 51 while(i>0) i--; 52 return b; 53 } 54 55 //读取一字节数据, 通过调用readBit()来实现 56 unsigned char readByte() 57 { 58 unsigned int i; 59 unsigned char j, dat; 60 dat = 0; 61 for(i=0; i<8; i++) 62 { 63 j = readBit(); 64 //最先读出的是最低位数据 65 dat = (j << 7) | (dat >> 1); 66 } 67 return dat; 68 } 69 70 //向DS18B20写入一字节数据 71 void writeByte(unsigned char dat) 72 { 73 unsigned int i; 74 unsigned char j; 75 bit b; 76 for(j = 0; j < 8; j++) 77 { 78 b = dat & 0x01; 79 dat >>= 1; 80 //写"1", 让低电平持续2个小延时, 高电平持续8个小延时 81 if(b) 82 { 83 ds = 0; 84 i++; i++; 85 ds = 1; 86 i = 8; while(i>0) i--; 87 } 88 else //写"0", 让低电平持续8个小延时, 高电平持续2个小延时 89 { 90 ds = 0; 91 i = 8; while(i>0) i--; 92 ds = 1; 93 i++; i++; 94 } 95 } 96 } 97 98 //向DS18B20发送温度转换命令 99 void sendChangeCmd() 100 { 101 dsInit(); //初始化DS18B20 102 delay(1); //延时1ms 103 writeByte(0xcc); //写入跳过序列号命令字 104 writeByte(0x44); //写入温度转换命令字 105 } 106 107 //向DS18B20发送读取数据命令 108 void sendReadCmd() 109 { 110 dsInit(); 111 delay(1); 112 writeByte(0xcc); //写入跳过序列号命令字 113 writeByte(0xbe); //写入读取数据令字 114 } 115 116 //获取当前温度值 117 unsigned int getTmpValue() 118 { 119 unsigned int value; //存放温度数值 120 float t; 121 unsigned char low, high; 122 sendReadCmd(); 123 //连续读取两个字节数据 124 low = readByte(); 125 high = readByte(); 126 //将高低两个字节合成一个整形变量 127 value = high; 128 value <<= 8; 129 value |= low; 130 //DS18B20的精确度为0.0625度, 即读回数据的最低位代表0.0625度 131 t = value * 0.0625; 132 //将它放大10倍, 使显示时可显示小数点后一位, 并对小数点后第二2进行4舍5入 133 //如t=11.0625, 进行计数后, 得到value = 111, 即11.1 度 134 value = t * 10 + 0.5; 135 return value; 136 } 137 138 //显示当前温度值, 精确到小数点后一位 139 void display(unsigned int v) 140 { 141 unsigned char count; 142 unsigned char datas[] = {0, 0, 0}; 143 datas[0] = v / 100; 144 datas[1] = v % 100 / 10; 145 datas[2] = v % 10; 146 for(count = 0; count < 3; count++) 147 { 148 //片选 149 wela = 0; 150 P0 = ((0xfe << count) | (0xfe >> (8 - count))); //选择第(count + 1) 个数码管 151 wela = 1; //打开锁存, 给它一个下降沿量 152 wela = 0; 153 //段选 154 dula = 0; 155 if(count != 1) 156 { 157 P0 = table[datas[count]]; //显示数字 158 } 159 else 160 { 161 P0 = tableWidthDot[datas[count]]; //显示带小数点数字 162 } 163 dula = 1; //打开锁存, 给它一个下降沿量 164 dula = 0; 165 delay(5); //延时5ms, 即亮5ms 166 167 //清除段先, 让数码管灭, 去除对下一位的影响, 去掉高位对低位重影 168 //若想知道影响效果如何, 可自行去掉此段代码 169 //因为数码管是共阴极的, 所有灭的代码为: 00H 170 dula = 0; 171 P0 = 0x00; //显示数字 172 dula = 1; //打开锁存, 给它一个下降沿量 173 dula = 0; 174 } 175 } 176 177 void main() 178 { 179 unsigned char i; 180 unsigned int value; 181 while(1) 182 { 183 //启动温度转换 184 sendChangeCmd(); 185 value = getTmpValue(); 186 //显示3次 187 for(i = 0; i < 3; i++) 188 { 189 display(value); 190 } 191 } 192 } 显示效果:   流程图:   改进代码: 扩大测量范围, 使可测量范围为: -55度 ~ +125度, 严格按照上面的流程进行软件设计 3.15 1:34 修正display()函数中的下一位显示对上一位的影响   改进代码 1 #include 2 #include 3 #include //要用到取绝对值函数abs() 4 //通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值, 目前显示范围: -55~ +125度 5 sbit wela = P2^7; //数码管位选 6 sbit dula = P2^6; //数码管段选 7 sbit ds = P2^2; 8 int tempValue; 9 10 //0-F数码管的编码(共阴极) 11 unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66, 12 0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; 13 //0-9数码管的编码(共阴极), 带小数点 14 unsigned char code tableWidthDot[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 15 0x87, 0xff, 0xef}; 16 17 //延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms. 18 void delay(unsigned int i) 19 { 20 unsigned int j; 21 while(i--) 22 { 23 for(j = 0; j < 125; j++); 24 } 25 } 26 27 //初始化DS18B20 28 //让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动 29 void dsInit() 30 { 31 //对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于为8us 32 unsigned int i; 33 ds = 0; 34 i = 100; //拉低约800us, 符合协议要求的480us以上 35 while(i>0) i--; 36 ds = 1; //产生一个上升沿, 进入等待应答状态 37 i = 4; 38 while(i>0) i--; 39 } 40 41 void dsWait() 42 { 43 unsigned int i; 44 while(ds); 45 while(~ds); //检测到应答脉冲 46 i = 4; 47 while(i > 0) i--; 48 } 49 50 //向DS18B20读取一位数据 51 //读一位, 让DS18B20一小周期低电平, 然后两小周期高电平, 52 //之后DS18B20则会输出持续一段时间的一位数据 53 bit readBit() 54 { 55 unsigned int i; 56 bit b; 57 ds = 0; 58 i++; //延时约8us, 符合协议要求至少保持1us 59 ds = 1; 60 i++; i++; //延时约16us, 符合协议要求的至少延时15us以上 61 b = ds; 62 i = 8; 63 while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求 64 return b; 65 } 66 67 //读取一字节数据, 通过调用readBit()来实现 68 unsigned char readByte() 69 { 70 unsigned int i; 71 unsigned char j, dat; 72 dat = 0; 73 for(i=0; i<8; i++) 74 { 75 j = readBit(); 76 //最先读出的是最低位数据 77 dat = (j << 7) | (dat >> 1); 78 } 79 return dat; 80 } 81 82 //向DS18B20写入一字节数据 83 void writeByte(unsigned char dat) 84 { 85 unsigned int i; 86 unsigned char j; 87 bit b; 88 for(j = 0; j < 8; j++) 89 { 90 b = dat & 0x01; 91 dat >>= 1; 92 //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1 93 if(b) 94 { 95 ds = 0; 96 i++; i++; //拉低约16us, 符号要求15~60us内 97 ds = 1; 98 i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求 99 } 100 else //写"0", 将DQ拉低60us~120us 101 { 102 ds = 0; 103 i = 8; while(i>0) i--; //拉低约64us, 符号要求 104 ds = 1; 105 i++; i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了 106 } 107 } 108 } 109 110 //向DS18B20发送温度转换命令 111 void sendChangeCmd() 112 { 113 dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化 114 dsWait(); //等待DS18B20应答 115 delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号 116 writeByte(0xcc); //写入跳过序列号命令字 Skip Rom 117 writeByte(0x44); //写入温度转换命令字 Convert T 118 } 119 120 //向DS18B20发送读取数据命令 121 void sendReadCmd() 122 { 123 dsInit(); 124 dsWait(); 125 delay(1); 126 writeByte(0xcc); //写入跳过序列号命令字 Skip Rom 127 writeByte(0xbe); //写入读取数据令字 Read Scratchpad 128 } 129 130 //获取当前温度值 131 int getTmpValue() 132 { 133 unsigned int tmpvalue; 134 int value; //存放温度数值 135 float t; 136 unsigned char low, high; 137 sendReadCmd(); 138 //连续读取两个字节数据 139 low = readByte(); 140 high = readByte(); 141 //将高低两个字节合成一个整形变量 142 //计算机中对于负数是利用补码来表示的 143 //若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value 144 tmpvalue = high; 145 tmpvalue <<= 8; 146 tmpvalue |= low; 147 value = tmpvalue; 148 149 //使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度 150 t = value * 0.0625; 151 //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入 152 //如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度 153 //如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度 154 value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5 155 return value; 156 } 157 158 unsigned char const timeCount = 3; //动态扫描的时间间隔 159 //显示当前温度值, 精确到小数点后一位 160 //若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码 161 void display(int v) 162 { 163 unsigned char count; 164 unsigned char datas[] = {0, 0, 0, 0, 0}; 165 unsigned int tmp = abs(v); 166 datas[0] = tmp / 10000; 167 datas[1] = tmp % 10000 / 1000; 168 datas[2] = tmp % 1000 / 100; 169 datas[3] = tmp % 100 / 10; 170 datas[4] = tmp % 10; 171 if(v < 0) 172 { 173 //关位选, 去除对上一位的影响 174 P0 = 0xff; 175 wela = 1; //打开锁存, 给它一个下降沿量 176 wela = 0; 177 //段选 178 P0 = 0x40; //显示"-"号 179 dula = 1; //打开锁存, 给它一个下降沿量 180 dula = 0; 181 182 //位选 183 P0 = 0xfe; 184 wela = 1; //打开锁存, 给它一个下降沿量 185 wela = 0; 186 delay(timeCount); 187 } 188 for(count = 0; count != 5; count++) 189 { 190 //关位选, 去除对上一位的影响 191 P0 = 0xff; 192 wela = 1; //打开锁存, 给它一个下降沿量 193 wela = 0; 194 //段选 195 if(count != 2) 196 { 197 /* if((count == 0 && datas[count] == 0) 198 || ((count == 1 && datas[count] == 0) && (count == 0 && datas[count - 1] == 0))) 199 { 200 P0 = 0x00; //当最高位为0时, 不作显示 201 } 202 else*/ 203 P0 = table[datas[count]]; //显示数字 204 } 205 else 206 { 207 P0 = tableWidthDot[datas[count]]; //显示带小数点数字 208 } 209 dula = 1; //打开锁存, 给它一个下降沿量 210 dula = 0; 211 212 //位选 213 P0 = _crol_(0xfd, count); //选择第(count + 1) 个数码管 214 wela = 1; //打开锁存, 给它一个下降沿量 215 wela = 0; 216 delay(timeCount); 217 } 218 } 219 220 void main() 221 { 222 unsigned char i; 223 224 while(1) 225 { 226 //启动温度转换 227 sendChangeCmd(); 228 //显示5次 229 for(i = 0; i < 40; i++) 230 { 231 display(tempValue); 232 } 233 tempValue = getTmpValue(); 234 } 235 } 改进后的效果图: 只有一位小数   两位小数, 并消除下一位对上一位的影响  

    时间:2019-07-10 关键词: ds18b20 单片机练习 温度转换与显示

  • 数码管显示51单片机DS18B20温度测量源程序及仿真

    这是一款数码管显示51单片机DS18B20温度测量源程序及仿真资料,特别适合单片机初学者学习参考,这款数码管显示51单片机DS18B20温度测量源程序使用模块化编程,方便移置,单片机使用AT89C51单片机,数码使用四位共阴数码管,这样简化了硬件电路,降低了硬件的制作难度。这款数码管显示51单片机DS18B20温度测量源程序是在Keil4环境下编译通过,并在Proteus7.8仿真软件下仿真通过。温度测量范围是:-55-125度。由于源程序直接贴出来会丢后些重要内容,所以特别将这款数码管显示51单片机DS18B20温度测量源程序及仿真资料打包后放在百度网盘上,需要的爱好者可以自己去下载。    

    时间:2019-07-01 关键词: 51单片机 温度测量 ds18b20 数码管显示

  • DS18B20制作的温度测量模块

    DS18B20制作的温度测量模块,这款能显示正负值的单片机DS18B20测温模块是由电子乐屋源创制作,单片机驱动数码管的端口设置成推挽工作方式,这样使用整个显示电路比较简单,数码管段驱动端省去了限流电阻,数码管亮度显示通过程序控制通断时间实现。只使用了6只元件:一只DS18B20数字温度传感器、一个USB插口、一片STC12C4052单片机、一个4位一体共阳数码管,一个10uf贴片复位电容、一个10k的贴片复位电阻。由于电路比较简单,这里直接给出PCB图,设计温度测量范围是:-9.9~99.9℃,下面是制作过程,文后附有源程序,源程序适合于STC1T单片机。下图是制作好的实物工作照片。         为了方便单片机爱好都仿制,附上源程序:注意(贴出来的程序可能头文件会发生变化,注意自己修改一下 //使用单片机内部RC振荡器 #include #include #define uchar unsigned char #define uint unsigned int sfr P1M0 = 0x91; sfr P1M1 = 0x92; sfr P3M0 = 0xB1; sfr P3M1 = 0xB2; #define ENABLE_ISP 0x84 //系统工作时钟<6MHz 时,对IAP_CONTR 寄存器设置此值 sbit temp=P1^7; sbit LED0=P3^0; //C sbit LED1=P1^4; // 小数点后一位 sbit LED2=P1^3; //个位 sbit LED3=P1^0; // 十位 sbit A=P1^1; sbit B_B=P1^5; sbit C=P3^2; sbit D=P3^4; sbit E=P3^5; sbit F=P1^2; sbit G=P3^1; sbit H=P3^3; //小数点 uchar temp_low,zf,mz; int temp_high; int final_temp; void dm(mz); void delay(uint x) //(x+1)*6微 { while(x--); } void delay_long(uint x) { uint i; while(x--) { for(i=0;i<125;i++); } } void init_ds18b20()//初始化 { temp=1;//复位 delay(6);//稍作延时 temp=0; delay(145);//延时大于480us(520us) temp=1; delay(14);//这个时间不能太长,否则就过了检测信号的时间了 void read_signal()//读取应答脉冲 { while(temp); while(~temp)//检测到应答脉冲 { delay(7); break; } } bit readbit_ds18b20() { bit b; temp=1; delay(6);//稍作延时 temp=0; delay(2);//保持低最少1us(4us) temp=1; delay(4);//延时15us以后输出数据有效(23us) b=temp; delay(20);//读时间间隙不少于60us(71us) return(b); } void writebyte_ds18b20(uchar b)//写0写1一起完成 { int i,j; uchar btemp; temp=1; for(i=0;i<8;i++) { j=0; btemp=b&0x01; b>>=1; if(btemp==0) { temp=0; delay(18);//保持拉低在60us以上(71us) temp=1; } else { temp=0; j++;//15us之内拉高 temp=1; delay(18);//整个写时序时间在60us以上(71us) } } } void temp_convert() { init_ds18b20();//初始化 read_signal();//读取应答脉冲 delay_long(4); writebyte_ds18b20(0xcc);//跳过验证序列号命令,若单线上有多个ds18b20,则不可用这个命令 writebyte_ds18b20(0x44);//启动温度转换命令 } char readbyte_ds18b20() { uint i; uchar a,b; b=0; for(i=0;i<8;i++) { a=readbit_ds18b20(); b=(a< } return(b); } uint read_ds18b20() { int y; float yy; init_ds18b20();//初始化 read_signal();//读取应答脉冲 delay_long(4); writebyte_ds18b20(0xcc);//跳过验证序列号命令 writebyte_ds18b20(0xbbe);//读取内部ROM的数据 temp_low=readbyte_ds18b20();//读数据时低位在前,高位在后 temp_high=readbyte_ds18b20(); y=temp_high; y<<=8; y=y|temp_low;//整合为一个int型 yy=y*0.0625;//12位精度为0.0625 y=yy*10+0.5; return(y); } void display(uint x) { uchar sw,gw,xs; sw=x/100; gw=x0/10; //个位 xs=x; //小数 if(zf==1) { sw=11; } else { if(sw==0) { sw=12; } } dm(sw); LED3=1; delay(30); LED3=0; delay(10); dm(gw); LED2=1; delay(30); LED2=0; delay(10); dm(13); LED2=1; delay(10); LED2=0; delay(10); dm(xs); LED1=1; delay(30); LED1=0; delay(10); dm(10); LED0=1; delay(30); LED0=0; delay(10); } void dm(mz) { switch(mz) { case 0:A=0;B_B=0;C=0;D=0;E=0;F=0;G=1;H=1;break; case 1:A=1;B_B=0;C=0;D=1;E=1;F=1;G=1;H=1;break; case 2:A=0;B_B=0;C=1;D=0;E=0;F=1;G=0;H=1;break; case 3:A=0;B_B=0;C=0;D=0;E=1;F=1;G=0;H=1;break; case 4:A=1;B_B=0;C=0;D=1;E=1;F=0;G=0;H=1;break; case 5:A=0;B_B=1;C=0;D=0;E=1;F=0;G=0;H=1;break; case 6:A=0;B_B=1;C=0;D=0;E=0;F=0;G=0;H=1;break; case 7:A=0;B_B=0;C=0;D=1;E=1;F=1;G=1;H=1;break; case 8:A=0;B_B=0;C=0;D=0;E=0;F=0;G=0;H=1;break; case 9:A=0;B_B=0;C=0;D=0;E=1;F=0;G=0;H=1;break; case 10:A=0;B_B=1;C=1;D=0;E=0;F=0;G=1;H=1;break; //C case 11:A=1;B_B=1;C=1;D=1;E=1;F=1;G=0;H=1;break; //- case 12:A=1;B_B=1;C=1;D=1;E=1;F=1;G=1;H=1;break; //不显示 case 13:A=1;B_B=1;C=1;D=1;E=1;F=1;G=1;H=0;break; //小数点 } } void main(void) { P1M0 = 0x00; P1M1 = 0x19; P3M0=0x00; P3M1=0x01; LED0=0; //C LED1=0; // 小数点后一位 LED2=0; //个位 LED3=0; // 十位 read_ds18b20(); temp_convert(); delay_long(5); delay_long(2000);//delay(5)就是延时555us while(1) { temp_convert(); delay_long(5); final_temp=read_ds18b20(); if(final_temp<0) { final_temp=-(final_temp-1); zf=1; } else zf=0; display(final_temp); } }

    时间:2019-07-01 关键词: 温度测量 ds18b20

  • 基于DS18B20温度传感器和MQ2烟雾传感器的火灾报警器设计

    一、概述 火灾自动报警系统(Fire Alarm System,简称FAS系统)是人们为了早期发现通报火灾,并及时采取有效措施,控制和扑灭火灾,而设置在建筑物中或其它场所的一种自动消防设施,是人们同火灾作斗争的有力工具。 本设计中以温度探头和烟雾传感器作为火灾报警器的传感装置,并以LED和蜂鸣器作为示警装置。 二、功能 ●高温检测。传感器选用DS18B20,当环境温度大于40℃,高温报警指示灯亮,LCD1602第一行显示温度。 ●环境烟雾浓度检测。传感器选用MQ2烟雾传感器,AD0809作模数转换传烟雾浓度数据给单片机。当环境烟雾浓度大于50时,烟雾浓度指示灯亮,LCD1602第二行显示烟雾浓度。 当温度和烟雾浓度同时过高时,蜂鸣器发出报警声音。 三、硬件设计 温度传感器:DS18B20 烟雾传感器:MQ2。MQ2输出的模拟电压信号,使用ADC0809作模数转换后输入单片机。   四、程序设计   部分程序段: ○LCD1602显示部分程序 #define LCD_DATA P0 //lcd1602的引脚 sbit LCD_RS = P2^0; sbit LCD_RW = P2^1; sbit LCD_EN = P2^2; void LCD_Init(void) { Delay20ms(); LCD_WriteCmd(0x38); //8位机接口、双行显示、5×7字符点阵; LCD_WriteCmd(0x0c); //显示开启、光标不显示也不闪烁; LCD_WriteCmd(0x01); //清屏; LCD_WriteCmd(0x06); //光标右移一位、整屏不移动; LCD_Goto(0,0); } void LCD_WriteDat(unsigned char lcd_dat) { unsigned char tmp; tmp = LCD_ReadStatus(); //读状态; while((tmp & 0x80)) //是否忙 ? { tmp = LCD_ReadStatus(); } LCD_RS = 1; LCD_RW = 0; LCD_DATA = lcd_dat; _nop_(); LCD_EN = 0; _nop_(); _nop_(); LCD_EN = 1; } void LCD_WriteCmd(unsigned char lcd_cmd) { unsigned char tmp; tmp = LCD_ReadStatus(); while((tmp & 0x80)) { tmp = LCD_ReadStatus(); } LCD_RS = 0; LCD_RW = 0; LCD_DATA = lcd_cmd; _nop_(); LCD_EN = 0; _nop_(); _nop_(); LCD_EN = 1; } unsigned char LCD_ReadStatus(void) { unsigned char tmp; #if 0 LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; tmp = LCD_DATA; LCD_EN = 0; #endif LCD_DATA = 0xff; LCD_RS = 0; LCD_RW = 1; LCD_EN = 0; _nop_(); _nop_(); LCD_EN = 1; tmp = LCD_DATA; return tmp; } void LCD_Goto(unsigned char x,unsigned char y) { unsigned char tmp; if(y) //若是第二行; { tmp = 0xc0 + x; LCD_WriteCmd(tmp); } else { tmp = 0x80 + x; LCD_WriteCmd(tmp); } } void LCD_Display(unsigned char row,unsigned char *str) { if(row) { LCD_Goto(0,1); } else { LCD_Goto(0,0); } while(*str != '\0') { LCD_WriteDat(*str++); } } ○ADC0809部分程序 //AD0809的IO口以及变量定义 sbit OE=P2^7; sbit EOC=P2^6; sbit START=P3^0; void AD0809()//0809转换数据 { START=0;_nop_(); START=1;_nop_(); START=0;_nop_(); while(EOC==0); OE=1;_nop_(); density=P1;_nop_(); OE=0; } ○DS18B20部分程序 sbit DQ=P2^3; //DS18B20数据端 //2、DS18B2模块 void delay_18B20(unsigned int i) { while(i--); } //ds18b20初始化函数 void Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ复位 delay_18B20(2); //稍做延时 DQ = 0; //单片机将DQ拉低 delay_18B20(60); //精确延时 大于 480us DQ = 1; //拉高总线 delay_18B20(2); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(15); } //ds18b20读一个字节 unsigned char ReadOneChar(void) { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; // 给脉冲信号 dat>>=1; DQ = 1; // 给脉冲信号 if(DQ) dat |=0x80; delay_18B20(4); } return(dat); } //ds18b20写一个字节 void WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay_18B20(2); DQ = 1; dat>>=1; } } 五、仿真图   图3 火灾报警器仿真图

    时间:2019-07-01 关键词: 温度传感器 ds18b20 火灾报警器 烟雾传感器

  • 基于ARM9+Linux的DS18B20驱动程序设计

    基于ARM9+Linux的DS18B20驱动程序设计

    引言随着嵌入式技术的发展,基于ARM和Linux的嵌入式产品越来越多,DS18B20温度采集传感器在工业和生活上应用广泛,研究开发基于ARM9和Linux的DS18B20的驱动程序可以满足大部分温度采集平台的应用。1 Linux设备驱动的开发过程Linux操作系统通过各种驱动程序来操作硬件设备,它屏蔽了各种设备,设备驱动程序是操作系统内核和硬件之间的接口。从应用程序来看,硬件只是一个设备文件,应用程序可以像操作普通文件一样操作硬件设备。1.1 设备的分类Linux看待设备可区分为3种基本设备类型,分别为字符设备、块设备和网络设备:①字符设备:字符设备是一种可以当作一个字节流来存取的设备,相当于一个文件,字符设备驱动通常实现open、close、read和write系统调用;②块设备:如同字符设备,块设备通过位于/dev目录的文件系统结点来存取,块设备驱动程序主要通过传输固定大小的随机数据来访问设备,块设备驱动程序是核心内存与其他存储介质之间的管道;③网络设备:网络接口和一个已经挂载的块设备类似,网络接口使用特定的内核数据结构注册,与外界进行数据交换时调用,与块设备只响应来自内核的请求不同,Linux内核的网络子系统被设计成完全与协议无关,网络驱动程序异步地接收来自外界的数据包。1.2 字符设备开发过程本项目开发的驱动程序都是字符设备驱动程序,因此简单介绍字符设备的开发过程。1.2.1 重要的文件操作接口函数file_operationfile_operation是一个字符驱动如何建立底层驱动与应用程序连接的结构体,包含以下重要的函数接口:①int(*open)(struct inode*,struct file*):打开设备操作。②ssize_t(*read)(struct file*,char__user*,size_t,loff_t*):从设备中获取数据,非负返回值代表成功读取的字节数。③ssize_t(*write)(struct file*,const char__user*,size_t,loff_t*):发送数据给设备,非负返回值代表成功写入的字节数。④int(* ioctl)(struct inode*,struct file*,unsigned int,unsigned long):系统调用提供了发出设备特定命令的方法。1.2.2 设备打开与关闭open方法在应用程序调用open()系统调用时被调用,作用是打开设备;release方法在应用程序调用close()系统调用时被调用,作用是关闭设备。1.2.3 驱动程序与应用程序交换数据交换的方式最直接的方法是在struct file_operation中的read/write方法中与用户空间的buffer进行数据的交换:unsigned long copy_to_user(void__user*to,const void*from,unsigned long count):从内核空间拷贝数据到用户空间;unsigned long copy_from_user(void*to,const void__user*from,unsigned long count):从用户空间拷贝数据到内核空间;1.2.4 设备控制ioctl设备控制接口如下:①应用程序调用接口:int ioctl(int fd,unsigned longcmd,…):②设备驱动的相应接口:int(*ioctl)(struct inode*inode,struct file*filp,unsigned int cmd,unsigned long arg)。应用程序通过ioctl发送命令,从而调用驱动接口的ioctl。因此,在Linux字符设备驱动程序中主要实现open、read、write和ioctl函数分别对应Linux系统调用的open、read、write和ioctl来完成数据交互和设备操作。2 温度传感器驱动软件设计DS18B20采用独特的单总线接口方式,每只DS18B20都有一个唯一存储在ROM中的64位编码。最前面8位是单线系列编码:28H,接着的48位是一个唯一的序列号,最后8位是以上56位的CRC编码。通过单线总线端口访问DS18B20的协议如下:①初始化;②发送ROM操作指令;③发送DS18B20功能指令。主要功能指令,如表1所列。根据DS18B20的读写协议以及操作指令和功能指令,可以得出DS18B20的复位过程如图1所示,写操作流程如图2所示,读操作流程如图3所示。根据DS18B20复位、读写操作过程,利用Linux编写DS18B20驱动程序。过程描述如下。(1)复位操作流程①设总线为输出模式;②向总线发送一个上升沿,保持高电平100 ms;③向总线发送一个下降沿,保持低电平800 ms;④向总线发送一个上升沿,延时100 ms;⑤设总线为输入模式;⑥判断总线状态,如果为低电平,则复位成功。(2)写操作流程①设总线为输出模式,并设置8次循环;②向总线发送一个下降沿,保持低电平;③判断写入数据是0还是1,如果是1,则向总线发送一个上升沿,保持高电平;如果是0,则保持总线低电平不变;④延时60 ms,设总线为高电平,再延时15 ms;⑤循环操作步骤②~④;⑥设总线为高电平。(3)读操作流程①设循环次数为8;②设总线为输出,向总线发送一个下降沿,保持低电平,并延时1 ms;③向总线发送一个上升沿,并设为输入;④读总线状态,并保存为1位,并延时60 ms;⑤循环操作步骤②~④,读取1个字节数据。(4)温度读写过程①循环判断DS18B20直到复位,延时120ms;②写入CCH命令,跳过读序列号过程;③写入44H命令,开始温度转换,延时5 ms;④循环判断DS18B20直到复位,延时200 ms;⑤写入CCH命令,跳过读序列号过程;⑥写入BEH命令,读取寄存器;⑦读温度整数部分;⑧读温度小数部分。(5)驱动程序编写选定S3C2440一个GPIO引脚作为连接DS18B20的数据线,经过查电路图和S3C2440的芯片手册,选择GPF3为连接引脚;主要对GPF的控制寄存器GPFCON和数据寄存器GPFDAT进行操作,GPF3主要对应GPFCON第6位和第7位,以及GPFDAT的第3位进行操作;对GPFCON[7:6]设00为输人,设01为输出;GPFDAT[3]设为输入时,相应的位即为引脚的状态,设为输出则可以对引脚进行置1和置0操作;结合S3C2440的寄存器GPFCON和GPFDAT,以及DS18B20时序,可以利用C语言编写Linux下驱动程序,本驱动程序采用实现read接口函数的字符设备驱动。3 部分代码最后将data通过read接口函数发送到用户层——copy_to_user(buf,data,2),即将8位整数和8位小数部分送到用户层,完成一次数据读取过程。4 系统运行与测试加载驱动后,通过用户层调用驱动程序,图4为通过串口调试测试结果。结语完成了基于ARM9和Linux2.6.30的DS18B20驱动程序编写,实现了温度数据的采集以及传输。以ARM9为平台,基于Linux2.6.30开发DS18B20的驱动程序,以模块的形式加载到内核,最后通过应用层调用驱动,获得温度数据。

    时间:2019-03-21 关键词: Linux 电源技术解析 ds18b20

  • 51单片机——DS18B20

    DS18B20——温度传感器,单片机可以通过 1-Wire 和 DS18B20 进行通 信,最终将温度读出。1-Wire 总线的硬件接口很简单,只需要把 18B20 的数据引脚和单片 机的一个 IO 口接上就可以通信。最高12为的温度存储值,补码形式存储。2字节,LSB低字节,MSB高字节,-55~1251、初始化检测存在脉冲:总线上存在DS18B20,总线会根据时序要求返回一个低电平脉冲。单片机要拉低这个引脚,持续大概 480us到960us之间 的时间即可,我们的程序中持续了 500us。然后,单片机释放总线,就是给高电平,DS18B20 等待大概 15 到 60us 后,会主动拉低这个引脚大概是 60 到 240us,而后 DS18B20 会主动释放总线,这样 IO 口会被上拉电阻自动拉高。2、ROM操作指令Skip ROM(跳过ROM):0xCC。当总线上只有一个器件的时候,可以跳过 ROM,不进行ROM 检测。3、RAM存储器操作指令Read Scratchpad(读暂存寄存器):0xBE—— DS18B20 的温度数据是 2 个字节,我们读取数据的时候,先 读取到的是低字节的低位,读完了第一个字节后,再读高字节的低位,一直到两个字节全部 读取完毕。Convert Temperature(启动温度转换):0x44—— 12位最大的转换时间是 750ms4、DS18B20的位写时序当要给 DS18B20 写入‘0’的时候,单片机直接将引脚拉低,持续时间大于 60us 小于120us 就可以了。图上显示的意思是,单片机先拉低 15us 之后,DS18B20 会在从 15us 到60us 之间的时间来读取这一位,DS18B20 最早会 15us 的时刻读取,典型值是 30us 的时刻读取,最多不会超过 60us,DS18B20 必然读取完毕,所以持续时间超过 60us 即可。当要给DS18B20 写入‘1’的时候,单片机先将这个引脚拉低,拉低时间大于 1us,然后马上释放总线,即拉高引脚,并且持续时间也要大于 60us。和写‘0’类似的是,DS18B20 会在 15 到 60us 之间来读取这个‘1’。5、DS18B20的位读时序单片机首先要拉低这个引脚,并且至少保持1us 的时间,然后释放引脚,释放完毕后要尽快读取。从拉低这个引脚到读取引脚状态,不能超过 15us。大家从图 16-17 可以看出来,主机采样时间,也就是 MASTER SAMPLES,是 在15us 之内必须完成的。#include#includetypedefunsignedcharuchar;sbitIO_18B20=P3^2;//DS18B20通信引脚/*软件延时函数,延时时间(t*10)us*/voidDelayX10us(uchart){do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}while(--t);}/*复位总线,获取存在脉冲,以启动一次读写操作*/bitGet18B20Ack(){bitack;EA=0;//禁止总中断IO_18B20=0;//产生500us复位脉冲DelayX10us(50);IO_18B20=1;DelayX10us(6);//延时60usack=IO_18B20;//读取存在脉冲while(!IO_18B20);//等待存在脉冲结束EA=1;//重新使能总中断returnack;}/*向DS18B20写入一个字节,dat-待写入字节*/voidWrite18B20(uchardat){ucharmask;EA=0;//禁止总中断for(mask=0x01;mask!=0;mask

    时间:2019-01-16 关键词: 51单片机 ds18b20

  • 基于DS18B20温度传感器和MQ2烟雾传感器的火灾报警器设计

    一、概述火灾自动报警系统(Fire Alarm System,简称FAS系统)是人们为了早期发现通报火灾,并及时采取有效措施,控制和扑灭火灾,而设置在建筑物中或其它场所的一种自动消防设施,是人们同火灾作斗争的有力工具。【1】本设计中以温度探头和烟雾传感器作为火灾报警器的传感装置,并以LED和蜂鸣器作为示警装置。二、功能●高温检测。传感器选用DS18B20,当环境温度大于40℃,高温报警指示灯亮,LCD1602第一行显示温度。●环境烟雾浓度检测。传感器选用MQ2烟雾传感器,AD0809作模数转换传烟雾浓度数据给单片机。当环境烟雾浓度大于50时,烟雾浓度指示灯亮,LCD1602第二行显示烟雾浓度。当温度和烟雾浓度同时过高时,蜂鸣器发出报警声音。三、硬件设计温度传感器:DS18B20烟雾传感器:MQ2。MQ2输出的模拟电压信号,使用ADC0809作模数转换后输入单片机。四、程序设计部分程序段:○LCD1602显示部分程序#define LCD_DATA P0 //lcd1602的引脚sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;void LCD_Init(void){Delay20ms();LCD_WriteCmd(0x38); //8位机接口、双行显示、5×7字符点阵;LCD_WriteCmd(0x0c); //显示开启、光标不显示也不闪烁;LCD_WriteCmd(0x01); //清屏;LCD_WriteCmd(0x06); //光标右移一位、整屏不移动;LCD_Goto(0,0);}void LCD_WriteDat(unsigned char lcd_dat){unsigned char tmp;tmp = LCD_ReadStatus(); //读状态;while((tmp & 0x80)) //是否忙 ?{tmp = LCD_ReadStatus();}LCD_RS = 1;LCD_RW = 0;LCD_DATA = lcd_dat;_nop_();LCD_EN = 0;_nop_();_nop_();LCD_EN = 1;}void LCD_WriteCmd(unsigned char lcd_cmd){unsigned char tmp;tmp = LCD_ReadStatus();while((tmp & 0x80)){tmp = LCD_ReadStatus();}LCD_RS = 0;LCD_RW = 0;LCD_DATA = lcd_cmd;_nop_();LCD_EN = 0;_nop_();_nop_();LCD_EN = 1;}unsigned char LCD_ReadStatus(void){unsigned char tmp;#if 0LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;tmp = LCD_DATA;LCD_EN = 0;#endifLCD_DATA = 0xff;LCD_RS = 0;LCD_RW = 1;LCD_EN = 0;_nop_();_nop_();LCD_EN = 1;tmp = LCD_DATA;return tmp;}void LCD_Goto(unsigned char x,unsigned char y){unsigned char tmp;if(y) //若是第二行;{tmp = 0xc0 + x;LCD_WriteCmd(tmp);}else{tmp = 0x80 + x;LCD_WriteCmd(tmp);}}void LCD_Display(unsigned char row,unsigned char *str){if(row){LCD_Goto(0,1);}else{LCD_Goto(0,0);}while(*str != ''){LCD_WriteDat(*str++);}}○ADC0809部分程序//AD0809的IO口以及变量定义sbit OE=P2^7;sbit EOC=P2^6;sbit START=P3^0;void AD0809()//0809转换数据{START=0;_nop_();START=1;_nop_();START=0;_nop_();while(EOC==0);OE=1;_nop_();density=P1;_nop_();OE=0;}○DS18B20部分程序sbit DQ=P2^3; //DS18B20数据端//2、DS18B2模块void delay_18B20(unsigned int i){while(i--);}//ds18b20初始化函数void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay_18B20(2); //稍做延时DQ = 0; //单片机将DQ拉低delay_18B20(60); //精确延时 大于 480usDQ = 1; //拉高总线delay_18B20(2);x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败delay_18B20(15);}//ds18b20读一个字节unsigned char ReadOneChar(void){unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat |=0x80;delay_18B20(4);}return(dat);}//ds18b20写一个字节void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay_18B20(2);DQ = 1;dat>>=1;}}五、仿真图图3 火灾报警器仿真图

    时间:2019-01-14 关键词: 温度传感器 ds18b20 火灾报警器 烟雾传感器

  • 基于嵌入式ARM和DS18B20的数字测温系统

    前言  热误差是数控机床的最大误差源,数控机床的温度测试为机床热误差的补偿提供依据。传统的测温方案是将模拟信号通过电缆远距离传输至数据采集卡进行A/D转换并处理,实用中必须解决长线传输和模拟量传感器布线等问题。本文介绍了一种新型的设计方案,控制器采用SAMSUNG公司的32位ARM微控制器S3C44BOX,温度传感器采用单总线数字温度传感器DS18B20。采用数字温度传感器即在测试点完成了信号的数字化,提高了传输的可靠性,同时简化了外围电路,也便于传感器在机床上的布置安装。ARM处理器控制数字温度信号的采集,并与上位PC机通讯,同时其他硬件资源提供热补偿系统其他功能。本文在介绍数字温度传感器DS18B20的基础上,给出了系统的软硬件设计方案,对软件实现中的关键点做了详尽的注释说明。1 数字温度传感器DS18B20介绍  1.1 DS18B20的结构  DS18B20是美国DALLAS公司推出的一种可组网数字温度传感器。DS18B20只有一个数据输入/输出口,是单总线专用芯片。DS18B20工作时,被测温度值直接以单总线的数字方式传输。  DS18B20体积小,电压适用范围宽(3V-5V),可以通过编程实现9~12位的温度读数,即有可调的温度分辨率。测温范围-55℃~+125℃,在-10℃~+85℃时,精度为±0.5℃。其可选封装有TO-92、SOIC及CSP封装。  每个DS18B20出厂时都有一个唯一的64位序列号,因此一条总线上可以同时挂接多个DS18B20而不会出现混乱。  DS18B20包括一个暂存RAM和一个E2RAM。暂存存储器RAM用于存放工作参数和测量值,其作用是保证在单线通讯时的完整性,包括8个字节。E2RAM用于设定非易失性温度报警上下限值TH和TL(调电后依然保存)。内部结构如图1所示。图1 DS18B20内部存储器结构  头两个字节表示测得的温度读数,数据格式如图2所示:图2 温度字节的位定义  S=1时表示温度为负,S=0时表示温度为正,其余低位以二进制补码形式表示,最低位为1,表示0.0625℃内部存储器的第五个字节是结构寄存器,主要用于温度值的数字转换分辨率。  1.2 DS18B20的工作时序  DS18B20严格遵循单总线协议,工作时,主机先发一复位脉冲,使总线上的所有DS18B20都被复位,接着发送ROM操作指令,使序列号编码匹配的DS18B20被激活,准备接受下面的RAM访问指令。RAM访问指令控制选中的DS18B20工作状态,完成整个温度转换,读取等工作。在ROM命令发送之前,RAM命令命令不起作用。表1列出了所有操作命令。表1 指令系统表  整个操作主要包括三个关键过程:主机搜索DS18B20序列号、启动在线DS18B20做温度转换、读取温度值。  其工作流程如图3:图3 工作流程图  DS18B20对时序及电特性参数要求较高,必须严格按照DS18B20的时序要求去操作。它的数据读写主要由主机读写特定的时间片来完成,包括复位(初始化)、读时间片和写时间片。  (1)复位时序  使用DS18B20时,首先需将其复位,然后才能执行其它命令。复位时,主机将数据线拉为低电平并保持480μs~960μs,然后释放数据线,再由上拉电阻将数据线拉高15~60μs,等待DS18B20发出存在脉冲,存在脉冲有效时间为60~240μs,这样,就完成了复位操作。其复位时序如图4所示。图4 复位时序  (2)“写”时序  在主机对DS18B20写数据时,先将数据线置为高电平,再变为低电平,该低电平应大于1μs。在数据线变为低电平后15μs内,根据写“1”或写“0”使数据线变高或继续为低。DS18B20将在数据线变成低电平后15μs~60μs内对数据线进行采样。要求写入DS18B20的数据持续时间应大于60μs而小于120μs,两次写数据之间的时间间隔应大于1μs。写时隙的时序如图5所示。“读”时序机理类似,不再赘述。图5 “写”时序2 系统软硬件设计  2.1 硬件设计  我们采用的控制器是SAMSUNG公司的32位ARM微控制器S3C44BOX,是三星公司为一般应用提供的高性价比和高性能的微控制器的解决方案,功耗小,可靠性高。它使用ARM7TDMI核,工作在66MHz。采用的该ARM控制器将服务于整个热误差补偿系统,完成包括数据处理与通讯、控制等多任务的实现。机床测温系统只使用小部分片上资源。  我们主要通过对I/O引脚的电平读写来完成单总线的通讯,采用ARM内部的定时器产生中断来完成有时隙要求的工作。由于我们通过预分频后产生的计时值单位达到1μs,完全能够满足时序工作的需要。  DS18B20与控制器的接口及其简单,只需将DS18B20的信号线与控制器的一位双向端口连接即可。系统连接如图6所示:图6 系统连接图  2.2 软件设计  遵循DS18B20单总线通讯协议,温度转换与读取工作的软件流程可表示为图7(该流程是在已经选中激活某个选中的DS18B20以后,选中激活流程软件原理类似,此处省略)。图7 软件程序框图 可见,与DS18B20进行通讯主要完成以下三个基本子程序:初始化程序(复位程序)、‘读’子程序,‘写’子程序。系统采用 C语言进行设计,以下是初始化(复位)子程序,设计如下:  调用该初始化程序就可以实现复位要求。“读”子程序、“写”子程序实现机制类似,代码不再赘述。在单总线协议下,通过调用这几个子程序进行相应的控制,就能完成主机与DS18B20的通讯,实现温度的采集。3 结论  本系统接口电路简单,通讯可靠,集成后的系统运行良好,测试精度高,试验证明能完成预定测试任务。

    时间:2018-12-25 关键词: ARM ds18b20 数字测温系统

  • PIC入门6,DS18B20测温度

    程序如下://PIC C DS18B20测温,LCD显示.c 时间:2008-8-20//适合3ePIC实验板//C语言写的温度计,DS18B20测温,LCD显示,显示到0.1度//USING 16F877 READ MAXIM DS18b20 AND DISPLAY ON LCD1602 */#include //连线说明#define LCDRS RB1#define LCDRW RB2#define LCDE RB3#define LCDDATA PORTD#define DSDQ RB0 /* 连接ds18b20 */#define TRISDQ TRISB0//函数定义void lcdinit(); //双线模式void wcmd (char cmd);void wdata (char data);void poscursor(char line, char col);void print(char *s);void lcdbusy();void delay ( int t);void itoa10(unsigned char *buf, int i);int strlen (const char *s);void dsinit();void wdscmd(char cmd);float dsread ();//实数定义char bank1 title[]= "Temperature is";char dsfound[]="DS1820 FOUND";char dsnotfound[]="DS1820 NOT FOUND";char bank1 blank[]= " ";// LCD 命令定义#define CLRLCD 0X01#define LCDMOD 0X38 /* 8 BIT, TWO LINE, 5X7 DOT MATRIX */#define TURNON 0X0F /* turn on LCD, CURSOR, BLINKING */#define CURMODE 0X06 /* character don't move, cursor move right automaticall */// DS1820 命令定义#define SKIPROM 0XCC#define READSCRACHPAD 0XBE#define TCONVERT 0X44/* ORIGINAL CURSOR POSITION */#define ORG1 0X80#define ORG2 0XC0//TMR0 中断static int count;#define PRETMR0 210 // 50us时间间隔float temperature;#define DSRESET 10#define DSRECOVER 1char bank1 atemperature[10]; // 数子温度//主函数void main(){int len;ADCON1=0X07; //设置端口A为I/Olcdinit();print(title);LCDE=0; /* 当 LCDE=0,LCD不起作用,操纵DS1820 *//* 中断TIMER0 */OPTION=0B11001111; // bit5=0,利用内部循环时钟TMR0IE=1; //timer0 使能端PEIE=0; //关闭所有外设中断GIE=1;//开总中断poscursor(1,0);while (1) {dsinit();wdscmd(SKIPROM);wdscmd(TCONVERT);TRISDQ=0;DSDQ=0;TRISDQ=1;while(1){ //转换是否完成if (DSDQ)break;elsecontinue;}dsinit();wdscmd(SKIPROM);wdscmd(READSCRACHPAD);temperature=dsread(); // 读温度itoa10(atemperature, (int) (temperature * 10)); //itoa10只有是正数时起作用// 所以乘以10,扩大10倍,然后增加小数点// 再最后一个数前增加小数点len=strlen(atemperature);atemperature[len]=atemperature[len-1];atemperature[len-1]='.';atemperature[len+1]=0;poscursor(0,0);print (title);poscursor(1,0);print (blank);poscursor(1,2);print (atemperature);print (blank);delay(10000); //再得到新的温度前延时10000*50 us=0.5 s}}//延时函数void delay (int t){count=0; // 重设置中断 timer 0 */TMR0=PRETMR0;while (count0;i--);}else {DSDQ=0 ;delay(1);for (i=5;i>0;i--);TRISDQ=1;}cmd=cmd/2;}}//读温度float dsread () {char tmp=0x01;float t;union{char c[2];int x;}temp;temp.x=0;while (tmp){ //读8字节TRISDQ=0;DSDQ=0;asm("NOP");TRISDQ=1; // 释放总线if (DSDQ) // "1" presentedtemp.c[0] |= tmp;tmp=tmp

    时间:2018-12-25 关键词: ds18b20 pic入门 测温度

  • DS18b20 温度检测说明

    **********************************************************************这是学习 msp430g2553 单片机时写的DS18b20 的程序 ****DS18b20单总线,时序严格,完全自学明白浪费了n久!!****最高精度0.0625,即温度每变 0.0625 就能被检测到****网上一些 *0.0625 、*256/1000、/16 的都是错误的(I think) ****DQ 接 p2.4********************************************************************************************************************************************DS18b20 操作时序:****1. DS18b20 初始化****2. 对64位ROM进行操作****读ROM****搜索ROM****跳过ROM****告警搜索****3. 对寄存器进行操作****4. 精度默认的为0.0625 ,无法重新设定,没找到相应的指令****相对应的转换时间为750ms**********************************************************************#include#include#define DQ_1 P2OUT |= BIT4#define DQ_0 P2OUT &= ~BIT4#define DQ_inP2DIR &= ~BIT4#define DQ_outP2DIR |= BIT4#define DQ_val(P2IN & BIT4)#define Read_ROM0x33//读ROM#define Match_ROM 0x55//匹配ROM#define Skip_ROM 0xcc//跳过ROM#define Search_ROM 0xf0//搜索ROM#define Alarm_Search 0xec//告警搜索#define Convert_Temperature 0x44 //温度转换#define Read_Scratchpad 0xbe//读暂存存储器9字节内容#define Write_Scratchpad 0x4e//写暂存存储器,写的是TH and TL , 接着发送两位数据就可以******************************************************内部暂存存储器9字节内容****1. 温度低8位****2. 温度高8位****3. 温度上限TH****4. 温度下线TL****5. 配置****6.7.8 保留****9. CRC 校验码******************************************************unsigned int Check_val; //初始化检测变量unsigned int Temp;//温度整数值******************************************************************************************DS18b20 初始化方法:****1 主机发送 480 - 960 us 的低电平,释放总线**** 2 等待 15 - 60 us**** 3 检测DQ上是否有低电平出现****有:复位成功 ,通常时间为 60-240 us****无:复位失败,继续等待****4 DQ上出现低电平后,低电平持续15us,然后DS18b20开始对单片机发送的数据进行采样******************************************************************************************unsigned intDS18b20_init(void){DQ_out;DQ_0;__delay_cycles(600);DQ_1;__delay_cycles(60);DQ_in;_NOP();if(DQ_val){Check_val = 0;//初始化失败}else{Check_val = 1;//初始化成功}__delay_cycles(10);DQ_out;DQ_1;__delay_cycles(100);return Check_val;}

    时间:2018-12-19 关键词: 温度检测 ds18b20

  • 数码管显示51单片机DS18B20温度测量源程序及仿真

    这是一款数码管显示51单片机DS18B20温度测量源程序及仿真资料,特别适合单片机初学者学习参考,这款数码管显示51单片机DS18B20温度测量源程序使用模块化编程,方便移置,单片机使用AT89C51单片机,数码使用四位共阴数码管,这样简化了硬件电路,降低了硬件的制作难度。这款数码管显示51单片机DS18B20温度测量源程序是在Keil4环境下编译通过,并在Proteus7.8仿真软件下仿真通过。温度测量范围是:-55-125度。由于源程序直接贴出来会丢后些重要内容,所以特别将这款数码管显示51单片机DS18B20温度测量源程序及仿真资料打包后放在百度网盘上,需要的爱好者可以自己去下载。更多单片机源程序与仿真请到电子乐屋。数码管显示51单片机DS18B20温度测量源程序及仿真http://pan.baidu.com/s/1c1OuRCG 密码:s4n2

    时间:2018-12-03 关键词: 51单片机 温度测量 ds18b20 数码管显示

  • 武林教你学PIC32(十八)单总线DS18B20温度传感器

    简单介绍下DS18B20,它是独特的单线接口,仅需一个端口进行通讯9~12位的分辨率可调(RS)测温范围为-55°C~+125°C;测量范围在-10°C ~+85°C精度为±0.5°C可设置报警温度存储于EEPROM,掉电保护数据不丢适用电压3~5.5V下面介绍我封装好的函数,已经测试可以使用,需要注意的是PORTReadBits,需要根据实际端口相应地移位DS18B20.H:#ifndef _DS18B20_H_#define _DS18B20_H_#include #define DQ_PORTIOPORT_D//设置DQ引脚#define DQ_PINBIT_14#define SET_OP_1WIREPORTSetBits(DQ_PORT, DQ_PIN)#define CLR_OP_1WIREPORTClearBits(DQ_PORT, DQ_PIN)#define SET_DIR_1WIREPORTSetPinsDigitalOut(DQ_PORT, DQ_PIN)#define CLR_DIR_1WIREPORTSetPinsDigitalIn(DQ_PORT, DQ_PIN)#define CHECK_IP_1WIREPORTReadBits(DQ_PORT, DQ_PIN)>>14extern void delay_us(unsigned int num);extern void delay_ms(unsigned int num);float gettemp(void);//读取温度值#endifDS18B20.C#include "ds18b20.h"void init_1820(){SET_DIR_1WIRE; //设置PC2为输出SET_OP_1WIRE;CLR_OP_1WIRE;delay_us(480);//480us以上SET_OP_1WIRE;CLR_DIR_1WIRE;delay_us(20);//15~60uswhile(CHECK_IP_1WIRE);SET_DIR_1WIRE;SET_OP_1WIRE;delay_us(140);//60~240us}void write_1820(unsigned char x){unsigned char m;for(m=0;m

    时间:2018-11-26 关键词: 温度传感器 pic32 ds18b20 单总线 武林

  • STM32系列第29篇--DS18B20

    特点:独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。测温范围 -55℃~+125℃,精度为±0.5℃。支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。测量结果以9~12位数字量方式串行传送。复位脉冲 & 应答信号单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240us,以产生低电平应答脉冲。写时序写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1:主机输出低电平,延时2us,然后释放总线,延时60us。写0:主机输出低电平,延时60us,然后释放总线,延时2us。读时序单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。读取过程复位→发SKIP ROM命令(0XCC)→发开始转换命令(0X44)→延时→复位→发送SKIPROM命令(0XCC)→发读存储器命令(0XBE)→连续读出两个字节数据(即温度)→结束。转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0, 这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际 温度。 例如+125℃的数字输出为07D0H,,-25.0625℃的数字输出为FE6FH。CODE://ds18b20.c#include"ds18b20.h"#include"delay.h"//复位DS18B20voidDS18B20_Rst(void){DS18B20_IO_OUT();//SETPG11OUTPUTDS18B20_DQ_OUT=0;//拉低DQdelay_us(750);//拉低750usDS18B20_DQ_OUT=1;//DQ=1delay_us(15);//15US}//等待DS18B20的回应//返回1:未检测到DS18B20的存在//返回0:存在u8DS18B20_Check(void){u8retry=0;DS18B20_IO_IN();//SETPG11INPUTwhile(DS18B20_DQ_IN&&retry=200)return1;elseretry=0;while(!DS18B20_DQ_IN&&retry=240)return1;return0;}//从DS18B20读取一个位//返回值:1/0u8DS18B20_Read_Bit(void){u8data;DS18B20_IO_OUT();//SETPG11OUTPUTDS18B20_DQ_OUT=0;delay_us(2);DS18B20_DQ_OUT=1;DS18B20_IO_IN();//SETPG11INPUTdelay_us(12);if(DS18B20_DQ_IN)data=1;elsedata=0;delay_us(50);returndata;}//从DS18B20读取一个字节//返回值:读到的数据u8DS18B20_Read_Byte(void){u8i,j,dat;dat=0;for(i=1;i1;if(testb){DS18B20_DQ_OUT=0;//Write1delay_us(2);DS18B20_DQ_OUT=1;delay_us(60);}else{DS18B20_DQ_OUT=0;//Write0delay_us(60);DS18B20_DQ_OUT=1;delay_us(2);}}}//开始温度转换voidDS18B20_Start(void){DS18B20_Rst();DS18B20_Check();DS18B20_Write_Byte(0xcc);//skipromDS18B20_Write_Byte(0x44);//convert}//初始化DS18B20的IO口DQ同时检测DS的存在//返回1:不存在//返回0:存在u8DS18B20_Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);//使能PORTG口时钟GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;//PORTG.11推挽输出GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOG,&GPIO_InitStructure);GPIO_SetBits(GPIOG,GPIO_Pin_11);//输出1DS18B20_Rst();returnDS18B20_Check();}//从ds18b20得到温度值//精度:0.1C//返回值:温度值(-550~1250)shortDS18B20_Get_Temp(void){u8temp;u8TL,TH;shorttem;DS18B20_Start();//ds1820startconvertDS18B20_Rst();DS18B20_Check();DS18B20_Write_Byte(0xcc);//skipromDS18B20_Write_Byte(0xbe);//convertTL=DS18B20_Read_Byte();//LSBTH=DS18B20_Read_Byte();//MSBif(TH>7){TH=~TH;TL=~TL;temp=0;//温度为负}elsetemp=1;//温度为正tem=TH;//获得高八位tem

    时间:2018-11-22 关键词: ds18b20 stm32系列

首页  上一页  1 2 3 4 5 下一页 尾页
发布文章

技术子站

更多

项目外包