ds18b20 订阅
DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。 [1]  DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。 展开全文
DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。 [1]  DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
信息
常见封装
TO-92、SOP8和DIP8
体    积
超低功耗
静态功耗<3uA
工作电压
3V~5.5V
抗干扰能力
中文名
数字温度传感器
采集模块
LCT2662M,RS485总线
外文名
DS18B20
硬件开销
DS18B20工作原理
DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。 DS18B20测温原理如图3所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。 [2] 
收起全文
精华内容
下载资源
问答
  • DS18B20

    2021-01-06 03:15:51
    <div><p>Hi, How to get the value of the connected sensor DS18B20 on the bus 1-ware through puthon</p><p>该提问来源于开源项目:homebridge/HAP-NodeJS</p></div>
  • 2线DS18B20程序
  • 基于stm32F1标准库开发的DS18B20驱动 timer.x提供时序控制支持 ds18b20.x是驱动内容,供以读取温度数据
  • 知道了怎么计算温度,接下来我们就来看看如何读取温度数据,由于DS18B20 是单总线器件,所有的单总线器件都要求采用严格的信号时序,以保证数据的完整性。DS18B20 时序包括如下几种:初始化时序、写(0和1)时序、读(0...

        知道了怎么计算温度,接下来我们就来看看如何读取温度数据,由于DS18B20 是单总线器件,所有的单总线器件都要求采用严格的信号时序,以保证数据的完整性。DS18B20 时序包括如下几种:初始化时序、写(0和1)时序、读(0 和 1)时序。DS18B20 发送所有的命令和数据都是字节的低位在前。这里我们简单介绍这几个信号的时序:

    (1)初始化时序

        单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少 480us (该时间的时间范围可以从 480 到 960 微妙) , 以产生复位脉冲。

        接着主机释放总线,外部的上拉电阻将单总线拉高,延时 15~60 us,并进入接收模式。接着 DS18B20 拉低总线 60~240 us,以产生低电平应答脉冲,若为低电平,还要做延时,其延时的时间从外部上拉电阻将单总线拉高算起最少要480微妙。初始化时序图如下:

    254cd91dc655cca4ed3e66d7e2f8f10a.png

    (2)写时序

        写时序包括写 0 时序和写 1 时序。所有写时序至少需要 60us,且在 2 次独立的写时序之间至少需要 1us 的恢复时间,两种写时序均起始于主机拉低总线。写 1 时序:主机输出低电平,延时 2us,然后释放总线,延时 60us。写 0时序:主机输出低电平,延时 60us,然后释放总线,延时 2us。写时序图如下:

    73004787c16a06056980a6873767d95a.png

    (3)读时序

        单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要 60us,且在 2 次独立的读时序之间至少需要 1us 的恢复时间。每个读时序都由主机发起,至少拉低总线 1us。主机在读时序期间必须释放总线,并且在时序起始后的 15us 之内采样总线状态。读时序图如下:

    a1ca48fbacd4b7226de8423197bb871e.png

        典型的读时序过程为:主机输出低电平延时 2us,然后主机转入输入模式延时 12us,然后读取单总线当前的电平,然后延时 50us。

        在了解了单总线时序之后,我们来看看 DS18B20 的典型温度读取过程,

    DS18B20 的典型温度读取过程为:复位→发 SKIP ROM 命令( 0XCC)→发开始转换命令( 0X44)→延时→复位→发送 SKIP ROM 命令( 0XCC)→发读存储器命令( 0XBE)→连续读出两个字节数据(即温度)→结束。

        到这里我们就介绍完了 DS18B20时序,如需更详细的介绍,请大家参考《DS18B20 中文》数据手册。

    硬件设计

        本实验使用到硬件资源如下:

    (1)D1 指示灯

    (2)串口 1

    (3)DS18B20 温度传感器

        D1指示灯、串口 1 电路在前面章节都介绍过,这里就不多说,DS18B20温度传感器模块电路如下图所示:

    7861084d45e1da12d6ddf78dc9c6f53f.png

    40aa3afedb65b7061ffc6abe61bd3457.png

        从电路图中可以看到,单总线接口连接在 STM32F1 芯片的 PG11管脚上,并且接了一个 10K 的上拉电阻。通过 PG11 管脚模拟单总线时序与 DS18B20 温度传感器通信。由于开发板标配是不带 DS18B20 温度传感器的,开发板上只提供接口DS1,所以做本章实验,大家需要准备一个 DS18B20 传感器插在预留的接口上,一定要注意温度传感器的方向,在接口处我们已经用丝印画了一个凸起,所以只需要将温度传感器对应插入即可。DS18B20 温度传感器接口如下图所示:

    33e7ee70cc03f6f575d0738fd1947139.png

        D1指示灯用来提示系统运行状态,DS18B20 温度传感器用来检测环境温度,串口 1用来打印输出温度传感器测试的温度值。

    展开全文
  • Ds18b20

    2020-05-01 16:29:24
    ds18b20检测温度,显示在数码管上 #include <reg52.h> #include <stdio.h> #include <intrins.h> typedef unsigned int u16; typedef unsigned char u8; typedef unsigned int uint; typedef ...

    ds18b20检测温度,显示在数码管上

    #include <reg52.h>
    #include <stdio.h>
    
    
    #include <intrins.h>
    
    typedef unsigned int u16;
    typedef unsigned char u8;
    typedef unsigned int uint;
    typedef unsigned char uchar;
    
    sbit DSPORT = P3^7;
    
    #define LED_CHOOSE	P2
    #define LED_VALUE	P0
    sbit le = P1^0;
    
    sbit LA = P2^2;
    sbit LB = P2^3;
    sbit LC = P2^4;
    
    u8 value_array[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77,
    0x39, 0x5e, 0x79, 0x71, 0x00, 0x80}; //0x00为无显示,0x80为小数点
    
    void delay(int i)
    {
    	while (i--);
    }
    
    void index_choose(u8 index)
    {
    	switch (index)
    	{
    		case 0:
    			LA = 0;
    			LB = 0;
    			LC = 0;
    			break;
    		case 1:
    			LA = 1;
    			LB = 0;
    			LC = 0;
    			break;
    		case 2:
    			LA = 0;
    			LB = 1;
    			LC = 0;
    			break;
    		case 3:
    			LA = 1;
    			LB = 1;
    			LC = 0;
    			break;
    		case 4:
    			LA = 0;
    			LB = 0;
    			LC = 1;
    			break;
    		case 5:
    			LA = 1;
    			LB = 0;
    			LC = 1;
    			break;
    		case 6:
    			LA = 0;
    			LB = 1;
    			LC = 1;
    			break;
    		case 7:
    			LA = 1;
    			LB = 1;
    			LC = 1;
    			break;
    		default:
    			break;
    	}
    }
    
    u8 cal_num_bit(int num)
    {
    	if (0 != (num / 10000))
    	{
    		return 5;
    	}
    
    	if (0 != num / 1000)
    	{
    		return 4;
    	}
    
    	if (0 != num / 100)
    	{
    		return 3;
    	}
    
    	if (0 != num / 10)
    	{
    		return 2;
    	}
    
    	if (0 != num / 1)
    	{
    		return 1;
    	}
    
    	return 0;
    }
    
    /*
    在数码管上显示数字,最多显示两位小数, 显示数字最大不超过:655.35
    类似:50.1  40  66.66  72.1
    */
    //#define FLOAT_SUPPORT (1)
    #if defined(FLOAT_SUPPORT)
    void nixue_tube_show_num(float num)
    {
    }
    #else
    void show_num_case1(int num)
    {
    	index_choose(0);
    	LED_VALUE = value_array[num];
    	delay(100);
    	LED_VALUE = 0x0;
    }
    
    void show_num_case2(int num)
    {
    	u8 i = 0;
    	u8 high = num / 10;
    	u8 low = num % 10;
    	u8 array[2] = {0};
    	array[0] = low;
    	array[1] = high;
    
    	for (i=0; i<sizeof(array)/sizeof(array[0]); i++)
    	{
    		index_choose(i);
    		LED_VALUE = value_array[array[i]];
    		delay(100);
    		LED_VALUE = 0x0;
    	}
    }
    
    void show_num_case3(int num)
    {
    	u8 i = 0;
    	u8 hundred = num / 100;
    	u8 high = num % 100 / 10;
    	u8 low = num % 10;
    	u8 array[3] = {0};
    	array[0] = low;
    	array[1] = high;
    	array[2] = hundred;
    
    	for (i=0; i<sizeof(array)/sizeof(array[0]); i++)
    	{
    		index_choose(i);
    		LED_VALUE = value_array[array[i]];
    		delay(100);
    		LED_VALUE = 0x0;
    	}
    }
    
    void show_num_case4(int num)
    {
    	u8 i = 0;
    	u8 thousand = num / 1000;
    	u8 hundred = num % 1000 / 100;
    	u8 high = num % 100 / 10;
    	u8 low = num % 10;
    	u8 array[4] = {0};
    	array[0] = low;
    	array[1] = high;
    	array[2] = hundred;
    	array[3] = thousand;
    
    	for (i=0; i<sizeof(array)/sizeof(array[0]); i++)
    	{
    		index_choose(i);
    		LED_VALUE = value_array[array[i]];
    		delay(100);
    		LED_VALUE = 0x0;
    	}
    }
    
    void show_num_case5(int num)
    {
    	u8 i = 0;
    	u8 ten_thousand = num / 10000;
    	u8 thousand = num % 10000 / 1000;
    	u8 hundred = num % 1000 / 100;
    	u8 high = num % 100 / 10;
    	u8 low = num % 10;
    	u8 array[5] = {0};
    	array[0] = low;
    	array[1] = high;
    	array[2] = hundred;
    	array[3] = thousand;
    	array[4] = ten_thousand;
    	
    	for (i=0; i<sizeof(array)/sizeof(array[0]); i++)
    	{
    		index_choose(i);
    		LED_VALUE = value_array[array[i]];
    		delay(100);
    		LED_VALUE = 0x0;
    	}
    }
    
    /*
    显示整数:最大不超过65535
    */
    void nixue_tube_show_num(int num)
    {
    	u8 ret = -1;
    	ret = cal_num_bit(num);
    	if (0 != ret)
    	{
    		switch (ret)
    		{
    			case 1:
    				show_num_case1(num);
    				break;
    			case 2:
    				show_num_case2(num);
    				break;
    			case 3:
    				show_num_case3(num);
    				break;
    			case 4:
    				show_num_case4(num);
    				break;
    			case 5:
    				show_num_case5(num);
    				break;
    			default:
    				break;
    		}
    	}
    }
    #endif
    
    void Delay1ms(int y)
    {
    	int x;
    	for( ; y>0; y--)
    	{
    		for(x=110; x>0; x--);
    	}
    }
    
    char Ds18b20Init()
    {
    	uchar i;
    	DSPORT = 0;			 //将总线拉低480us~960us
    	i = 70;	
    	while(i--);//延时642us
    	DSPORT = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
    	i = 0;
    	while(DSPORT)	//等待DS18B20拉低总线
    	{
    		Delay1ms(1);
    		i++;
    		if(i>5)//等待>5MS
    		{
    			return 0;//初始化失败
    		}
    	
    	}
    	return 1;//初始化成功
    }
    
    void Ds18b20WriteByte(uchar dat)
    {
    	uint i, j;
    
    	for(j=0; j<8; j++)
    	{
    		DSPORT = 0;	     	  //每写入一位数据之前先把总线拉低1us
    		i++;
    		DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始
    		i=6;
    		while(i--); //延时68us,持续时间最少60us
    		DSPORT = 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
    		dat >>= 1;
    	}
    }
    
    
    uchar Ds18b20ReadByte()
    {
    	uchar byte, bi;
    	uint i, j;	
    	for(j=8; j>0; j--)
    	{
    		DSPORT = 0;//先将总线拉低1us
    		i++;
    		DSPORT = 1;//然后释放总线
    		i++;
    		i++;//延时6us等待数据稳定
    		bi = DSPORT;	 //读取数据,从最低位开始读取
    		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
    		byte = (byte >> 1) | (bi << 7);						  
    		i = 4;		//读取完之后等待48us再接着读取下一个数
    		while(i--);
    	}				
    	return byte;
    }
    
    void  Ds18b20ChangTemp()
    {
    	Ds18b20Init();
    	Delay1ms(1);
    	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
    	Ds18b20WriteByte(0x44);	    //温度转换命令
    	//Delay1ms(100);	//等待转换成功,而如果你是一直刷着的话,就不用这个延时了
       
    }
    
    void  Ds18b20ReadTempCom()
    {	
    
    	Ds18b20Init();
    	Delay1ms(1);
    	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
    	Ds18b20WriteByte(0xbe);	 //发送读取温度命令
    }
    
    int Ds18b20ReadTemp()
    {
    	int temp = 0;
    	uchar tmh, tml;
    	Ds18b20ChangTemp();			 	//先写入转换命令
    	Ds18b20ReadTempCom();			//然后等待转换完后发送读取温度命令
    	tml = Ds18b20ReadByte();		//读取温度值共16位,先读低字节
    	tmh = Ds18b20ReadByte();		//再读高字节
    	temp = tmh;
    	temp <<= 8;
    	temp |= tml;
    	return temp;
    }
    
    int get_temp(void)
    {
    	float tp;
    	int temp = Ds18b20ReadTemp();
    	tp = temp;
    	temp = tp*0.0625;	
    	return temp;
    }
    
    
    
    void main(void)
    {
    	while(1)
    	{
    		nixue_tube_show_num(get_temp());
    		delay(500);		
    	}	
    }
    
    展开全文
  • 数字温度传感器, DS18B20,数字温度传感器, DS18B20,数字温度传感器, DS18B20,数字温度传感器, DS18B20,数字温度传感器, DS18B20,数字温度传感器, DS18B20,数字温度传感器, DS18B20,数字温度传感器, DS18B20,
  • 前言DS18B20是单片机课设或者仿真项目中一个比较常用的数字温度传感器,因此使用DS18B20仿真一个简易的温控器,超过温度就打开风扇,低于某温度就用继电器打开加热丝。整个程序我都会附在最后,如果懒得复制粘贴,要...

    21f5aeb654e472383f107ae12664d81d.png

    前言

    DS18B20是单片机课设或者仿真项目中一个比较常用的数字温度传感器,因此使用DS18B20仿真一个简易的温控器,超过温度就打开风扇,低于某温度就用继电器打开加热丝。整个程序我都会附在最后,如果懒得复制粘贴,要所有的工程以及仿真的话,就给我点赞赏吧。

    整个仿真如图:

    4d88b8d87b2b01d970063f88e2e2931f.png

    首先便是查找DS18B20的手册,编写DS18B20的驱动程序。阅读手册可知:

    DS18B20的数据类型

    DS18B20提供9位与12位摄氏温度测量进度,上电默认是12位,如果我们就用默认的12位精度的话,那么最后从DS18B20读出来的数据要乘以0.0625,之后得到的就是实际温度,单位摄氏度。测量范围为 -55℃至125℃。

    DS18B20的通信方式

    DS18B20是单总线接口,也就是说,只需要一个通信接口与单片机进行通信,DS18B20看起来就比较像三极管,但它是两根电源线+一根通信线,每个DS18B20都有一个独一无二的64位序列号,也就是说,在一个总线上可以连接多个DS18B20设备,控制不同的DS18B20来读取多点温度。

    DS18B20的外围电路

    DS18B20的电路部分也很简单,不需要外围元件,使用3V-5.5V供电。

    DS20B20的控制流程

    DS18B20上电默认是12位精度,主设备必须向DS18B20发送温度转换命令[44H]才能开始温度转换。当然DS18B20进行温度转换需要时间,当发送完[44H]读命令之后,主设备就可以执行读数据时序了,等待DS18B20转换完成,在DS18B20转换完成之前,都会返回0,转换完成之后,就会返回1。

    DS18B20的温度数据是以一个16位二进制补码数的形式存储在温度寄存器中。我们现在就确定使用12位精度的形式,那么首位就为符号位,之后是数据位,如图:

    c2be24f53ec2899fb3c9a2da4e75d26b.png

    此外要注意这个上电复位时默认是85℃,有些人看到上电85度还以为是错的,因此疯狂修改程序,其实是正常现象,自己程序注意一下即可。

    了解了这些,我们就开始着手写DS18B20的驱动程序。
    手册上对于事件流程的说明如图:

    6e4c187d1ccf8cdcaaaec40c2d9252f0.png

    注意最后一句话:当执行完这些ROM命令之后,主设备必须回到上述步骤中的第一步。也就是说,我们首先需要进行初始化,然后发送ROM命令,然后发送功能命令。之后便是等待ROM命令执行完,如果要发送下一个ROM命令,则又需要重新回到第一步初始化,再发送下一个ROM命令,再发送功能命令。这一点需要记住。

    那么我们的整个读取流程就基本确定了:
    初始化->跳过读序列号(ROM命令)->启动温度转化(功能命令)->延时等待ROM命令与温度转换执行结束->初始化->跳过读序列号(ROM命令)->读取温度(功能命令)

    因为我们就使用一个DS18B20,因此可以跳过这个读序列号。下面我们就按照这个流程来编写各部分程序。

    初始化

    7c6602a06a725367cef19ba57561b5f4.png

    由时序图可知,初始化程序首先需要将总线拉为低电平至少480us的时间,然后释放总线,总线置为高电平,DS18B20就会检测这个上升沿,检测到上升沿之后,等待15-60us,将总线再拉低至少480us,也就是说,高电平的时间也要持续15-60us。

    初始化程序如下:

    /@@****************************************************************************
    函数功能:延时子程序
    ****************************************************************************/
    void delay(uint k)
    {
        while(k--);
    }
    /@@****************************************************************************
    函数功能:DS18B20初始化子程序
    ****************************************************************************/
    void ds18b20_init(void)
    {
        DQ=1; //DQ先置高
        delay(16); //延时
        DQ = 0; //发送复位脉冲
        delay(80); //延时(&amp;amp;amp;gt;480us)
        DQ = 1; //拉高数据线
        delay(16); //等待(15~60us)
        delay(60);
        DQ = 1;
    }

    写数据

    写数据分为写0和写1,在DS18B20中分为写0时段和写1时段,每个写时段最小必须由60us的时序时间并且要有1us的恢复时间。

    5f198af8a6cddcc2cc88e64c16e0ae8b.png

    在写1时段,在总线拉低之后,主设备必须在15us之内释放总线,总线释放后,上拉电阻将总线拉高;在写0时段,在总线拉低后,整个时段必须一致拉低总线,至少60us。

    简单来说,就是这样:在主设备初始化写时段后,DS18B20会在15-60us内对总线进行采样,如果采样时候是高电平,则DS18B20会写入1,反之则写入0。

    程序如下:

    /****************************************************************************
    
    函数功能:向DS18B20写一字节数据
    
    入口参数:dat
    
    出口参数:
    
    ****************************************************************************/
    void WriteOneChar(uchar dat)
    {
    	uchar i=0;
    	DQ=1;
    	delay(1);
    	for(i=8;i>0;i--)
    	{
    		DQ=0;
    		DQ=dat&0x01;
    		delay(5);
    		DQ=1;
    		dat>>=1;
    	}
    }

    读数据

    主设备在执行完读暂存寄存器[BEh]之后,需要即使生成读时段,才可以读取数据。每个读时段最小必须有60us的持续时间与1us的恢复时间。从DS18B20中发送出来的数据在读时序后仅有15us的有效时间,因此,主设备在开始读时段后的15us之内必须释放总线来读取数据。时序如上图所示。

    程序如下:

    /****************************************************************************
    
    函数功能:向DS18B20读一字节数据
    
    入口参数:
    
    出口参数:dat
    
    ****************************************************************************/
    
    uchar ReadOneChar(void)
    
    {
    	uchar i=0;
    	uchar dat=0;
    	DQ=1;
    	delay(1);
    	for (i=8;i>0;i--)
    	{
    		DQ=0;
    		dat>>=1;
    		DQ=1;
    		delay(1);
    		if(DQ)
    		dat|=0x80;
    		
    		delay(30);
    		DQ=1;
    	}
    
    	return dat;
    }

    然后就是根据手册查找一些重要的命令,包括跳过读序列号,读取温度命令等等,这一部分就不再赘述。然后我们就可以按照我们之前总结的读取温度的流程来编写整个读取温度的程序:

    /****************************************************************************
    
    函数功能:向DS18B20读温度值
    入口参数:
    出口参数:temperature
    
    温度读取流程: 初始化->跳过读序列号->启动温度转化->延时->初始化->跳过读序列号->读取温度并显示
    
    ****************************************************************************/
    float ReadTemperature(void)
    {
    	float  temperature = 0.0;
    	uint  temflag = 0;
    	uint  tt = 0;
    	uchar tempL=0; //临时变量低位
    	uchar tempH=0; //临时变量高位
    
    	ds18b20_init(); //初始化
    	WriteOneChar(0xcc); //跳过读序列号的操作
    	WriteOneChar(0x44); //启动温度转换
    	delay(125); //转换需要一点时间,延时
    
    	ds18b20_init(); //初始化
    	WriteOneChar(0xcc); //跳过读序列号的操作
    	WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
    	tempL=ReadOneChar(); //读出温度的低位LSB
    	tempH=ReadOneChar(); //读出温度的高位MSB
    	//温度转换,把高低位做相应的运算转化为实际温度
    	tt = tempH<<8;
    	tt = tt|tempL;
    
    	if(tt&0xf800)	//判断是否是负温度
    	{	//是负温度
    		tt = ~tt + 1; temflag = 0;
    	}
    	else
    	{
    		tt = tt; temflag = 1;
    	}
    	temperature = (float)tt;
    	temperature = temperature * 0.0625;
    //	delay(200);
    	
    	/*负温度*/
    	if(temflag == 0)
    	{
    		temperature = -temperature;
    	}
    	/*正温度*/
    	else
    	{
    		temperature = temperature;
    	}
    	return temperature;  //返回温度值
    }

    然后就是用1602来显示出来,看一下我们的程序对不对,关于1602的驱动程序,在我之前的文章中有说明,这里就不再说明。

    测试主程序如下:

    /@@*显示函数*/
    void display(void)
    {
       char *string1 = "TEM : ";
         char *string2 = " C   ";
       char *string3 = "High:";
       char *string4 = "Low:";    
       char Display1[16];  //第一行显示数组
         char Display2[16];  //第二行显示数组
         //显示温度
         sprintf((char*)Display1,"%s%d%s",string1,temp,string2);                           
         print_string(Display1,1);    
         //显示过温低温点
         sprintf((char*)Display2,"%s%d   %s%d",string3,tempOver,string4,tempLow);    
         print_string(Display2,2);
    }
    void main()
    {
       lcd_init();
         SW = 0;
         Motor = 0;
       while(1)
       {
              temp = (int)ReadTemperature();   //读取温度
               display();  //显示
       }
    }

    测试结果:

    18368c40e7954e4f9c62541ef5934987.png

    这里的显示程序中我加了阈值显示,这里设置的是高温阈值为30,低温阈值为27。因为为了后续方便,所以我就把阈值设置得比较近,这个可以自行修改。

    之后就是比较简单的逻辑了,超过高温阈值就关闭加热丝打开风扇,低于低温阈值就关闭风扇,打开加热丝。主程序如下:

    void main()
    {
       lcd_init();
    	 SW = 0;
    	 Motor = 0;
       while(1)
       {
       	   temp = (int)ReadTemperature();   //读取温度
    		   display();  //显示
    		 
    		   /*过温  打开风扇,关闭加热丝*/
    		   if(temp > tempOver)
    			 {
    				 SW = 0;   
    				 Motor = 1;
    			 }
    			 /*低温  关闭风扇,打开加热丝*/
    			 else if(temp < tempLow)
    			 {
    				 SW = 1;
    				 Motor = 0;
    			 }
       }
    }

    关于风扇的电路,我这里就直接用了一个ULN2003,这个是小电流电机的,如果要更换24V大电流电机驱动,或者要加上PWM调速,我后续会更新这方面的文章。

    效果如下:

    85a2d39231f6a4f78c0755f2cc0b06c0.png

    如果要全部的工程,仿真就点赞私聊我喔。

    1602程序在之前的文章中有发,因此1602程序就不发了。我的工程目录如下:

    763ad3468f590a808c9ef5c8c3ad48f7.png

    所有源代码如下:

    main.c

    #include <reg52.h>
    #include <stdio.h>
    #include "1602.h"
    #include "ds18b20.h"
    #define uchar unsigned char
    #define uint unsigned int
    
    sbit SW = P1^0;    //继电器控制加热丝
    sbit Motor = P1^1; //电机接口
    
    int temp = 0;   //存储温度
    int tempOver = 30;   //过温温度
    int tempLow  = 27;   //低温温度
    sbit key1 = P3^0;  //增加过温温度
    sbit key2 = P3^1;  //减小过温温度
    sbit key3 = P3^0;  //增加低温温度
    sbit key4 = P3^1;  //减小低温温度
    
    uint key_result = 0;  //保存按键结果
    
    
    void key_delay(uchar t)
    { 
    	int j;  
    	for(;t!=0; t--)  
    		 for (j=0;j<255;j++);  
    			
    }
    
    /*按键检测  如果按键1被按下就返回1 
    如果按键2被按下就返回2  如果没有按键按下就返回0*/
    uint key_scan(void)
    {
    	uint result = 0;
    	
    	/*先将按键电平拉高*/
    	key1 = 1;
    	key2 = 1;
    	
    	/*检测按键1是否被按下*/
    	if(key1 == 0)
    	{
    		key_delay(5);
    		if(key1 == 0)
    		{
    			result = 1;
    		}
    	}
    	
    	/*检测按键2是否被按下*/
    	if(key2 == 0)
    	{
    		key_delay(5);
    		if(key2 == 0)
    		{
    			result = 2;
    		}
    	}	
    	
    	return result; 
    }
    
    /*显示函数*/
    void display(void)
    {
       char *string1 = "TEM : ";
    	 char *string2 = " C   ";
       char *string3 = "High:";
       char *string4 = "Low:";	
       char Display1[16];  //第一行显示数组
    	 char Display2[16];  //第二行显示数组
    
    
    	 //显示温度
    	 sprintf((char*)Display1,"%s%d%s",string1,temp,string2);						   
    	 print_string(Display1,1);	
    	 
    	 //显示过温低温点
    	 sprintf((char*)Display2,"%s%d   %s%d",string3,tempOver,string4,tempLow);	
    	 print_string(Display2,2);
    }
    
    void main()
    {
       lcd_init();
    	 SW = 0;
    	 Motor = 0;
       while(1)
       {
       	   temp = (int)ReadTemperature();   //读取温度
    		   display();  //显示
    		 
    		   /*过温  打开风扇,关闭加热丝*/
    		   if(temp > tempOver)
    			 {
    				 SW = 0;   
    				 Motor = 1;
    			 }
    			 /*低温  关闭风扇,打开加热丝*/
    			 else if(temp < tempLow)
    			 {
    				 SW = 1;
    				 Motor = 0;
    			 }
       }
    }
    

    DS18B20源文件:

    #include <reg52.h>
    #include <stdio.h>
    #include "ds18b20.h"
    
    /***************************温度传感器信号引脚******************************************/
    sbit DQ=P1^5; //数据传输线接单片机的相应的引脚
    
    
    /****************************************************************************
    
    函数功能:延时子程序
    
    ****************************************************************************/
    void delay(uint k)
    {
    	while(k--);
    }
    
    /****************************************************************************
    
    函数功能:DS18B20初始化子程序
    
    ****************************************************************************/
    void ds18b20_init(void)
    {
    	DQ=1; //DQ先置高
    	delay(16); //延时
    	DQ = 0; //发送复位脉冲
    	delay(80); //延时(>480us)
    	DQ = 1; //拉高数据线
    	delay(16); //等待(15~60us)
    	delay(60);
    	DQ = 1;
    }
    
    /****************************************************************************
    
    函数功能:向DS18B20读一字节数据
    
    入口参数:
    
    出口参数:dat
    
    ****************************************************************************/
    
    uchar ReadOneChar(void)
    
    {
    	uchar i=0;
    	uchar dat=0;
    	DQ=1;
    	delay(1);
    	for (i=8;i>0;i--)
    	{
    		DQ=0;
    		dat>>=1;
    		DQ=1;
    		delay(1);
    		if(DQ)
    		dat|=0x80;
    		
    		delay(30);
    		DQ=1;
    	}
    
    	return dat;
    }
    
    
    /****************************************************************************
    
    函数功能:向DS18B20写一字节数据
    
    入口参数:dat
    
    出口参数:
    
    ****************************************************************************/
    void WriteOneChar(uchar dat)
    {
    	uchar i=0;
    	DQ=1;
    	delay(1);
    	for(i=8;i>0;i--)
    	{
    		DQ=0;
    		DQ=dat&0x01;
    		delay(5);
    		DQ=1;
    		dat>>=1;
    	}
    }
    
    
    /****************************************************************************
    
    函数功能:向DS18B20读温度值
    入口参数:
    出口参数:temperature
    
    温度读取流程: 初始化->跳过读序列号->启动温度转化->延时->初始化->跳过读序列号->读取温度并显示
    
    ****************************************************************************/
    float ReadTemperature(void)
    {
    	float  temperature = 0.0;
    	uint  temflag = 0;
    	uint  tt = 0;
    	uchar tempL=0; //临时变量低位
    	uchar tempH=0; //临时变量高位
    
    	ds18b20_init(); //初始化
    	WriteOneChar(0xcc); //跳过读序列号的操作
    	WriteOneChar(0x44); //启动温度转换
    	delay(125); //转换需要一点时间,延时
    
    	ds18b20_init(); //初始化
    	WriteOneChar(0xcc); //跳过读序列号的操作
    	WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
    	tempL=ReadOneChar(); //读出温度的低位LSB
    	tempH=ReadOneChar(); //读出温度的高位MSB
    	//温度转换,把高低位做相应的运算转化为实际温度
    	tt = tempH<<8;
    	tt = tt|tempL;
    
    	if(tt&0xf800)	//判断是否是负温度
    	{	//是负温度
    		tt = ~tt + 1; temflag = 0;
    	}
    	else
    	{
    		tt = tt; temflag = 1;
    	}
    	temperature = (float)tt;
    	temperature = temperature * 0.0625;
    //	delay(200);
    	
    	/*负温度*/
    	if(temflag == 0)
    	{
    		temperature = -temperature;
    	}
    	/*正温度*/
    	else
    	{
    		temperature = temperature;
    	}
    	return temperature;  //返回温度值
    }
    展开全文
  • DS18B20单线多点测温,设计中采用ATMEGA16单片机做控制,一个IO引脚接入两个DS18B20, 通过读取DS18B20的rom中的序列号,匹配不同的DS18B20 实现单线多点测温。单线挂载多个 DS18B20顺序读取,并通过LCD1602显示,有...

    DS18B20单线多点测温,设计中采用ATMEGA16单片机做控制,一个IO引脚接入两个DS18B20,

    通过读取DS18B20的rom中的序列号,匹配不同的DS18B20 实现单线多点测温。单线挂载多个

    DS18B20顺序读取,并通过LCD1602显示,有实现proteus仿真。

    开发环境为winavr。


          共同学习  q  :1425636507。

    展开全文
  • 前言DS18B20是单片机课设或者仿真项目中一个比较常用的数字温度传感器,因此使用DS18B20仿真一个简易的温控器,超过温度就打开风扇,低于某温度就用继电器打开加热丝。整个程序我都会附在最后,如果懒得复制粘贴,要...
  • ds18b20

    2017-02-12 09:05:05
    #include #include #include #include "1602.h" #include "delay.h" sbit ds = P0^0; sbit LED = P0^1;...void ds18b20_init(void) { ds = 0; DelayUs2x(200); DelayUs2x(200); ds = 1; Delay
  • 四、详细程序//复位DS18B20void DS18B20_Rst(void){DS18B20_IO_OUT(); //SET PG11 OUTPUTDS18B20_DQ_OUT=0; //拉低DQdelay_us(750); //拉低750usDS18B20_DQ_OUT=1; //DQ=1delay_us(15); //15US}//等待DS18B20的回应/...
  • STM32F103使用DS18B20读取代码 C语言 串口打印温度值temp=Get_DS18B20_Tmp()/10; //读取温度 // printf("%0.4lf \r\n",temp);

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,875
精华内容 1,950
关键字:

ds18b20