ds18b20温度采集

DS18B20的温度值显示程序设计

一.DS1820 单线数字温度计特性

• 独特的单线接口仅需一个端口引脚进行通讯
• 简单的多点分布应用
• 无需外部器件
• 可通过数据线供电
• 零待机功耗
• 测温范围-55~+125℃,以 0.5℃递增。华氏器件-67~+2570F,以 0.90F 递增
• 温度以 9 位数字量读出
• 温度数字量转换时间 200ms(典型值)
• 用户可定义的非易失性温度报警设置
• 报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件
• 应用包括温度控制、工业系统、消费品、温度计或任何热感测系统

二. ROM 操作指令

Read ROM(读 ROM) [33H]
Match ROM(匹配 ROM) [55H]
Skip ROM(跳过 ROM] [CCH]
Search ROM(搜索 ROM) [F0H]
Alarm search(告警搜索) [ECH]

三. 存储器操作命令

Write Scratchpad(写暂存存储器) [4EH]
Read Scratchpad(读暂存存储器) [BEH]
Copy Scratchpad(复制暂存存储器) [48H]
Convert Temperature(温度变换) [44H]
Recall EPROM(重新调出) [B8H]
Read Power supply(读电源) [B4H]
话不多说,直接上代码。

1.初始化子函数

主机将数据线DQ拉低480us后释放总线,延时15 ~ 60 us 后的60 ~ 240 us时间内检测DQ是否为低电平,再延时240us 保证起始时序的完整。
初始化

bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;             //主机拉低总线
  	Delay_OneWire(12);
  	DQ = 0;             //主机释放总线

  	Delay_OneWire(80); // 延时大于480us
  	DQ = 1;
  	Delay_OneWire(10);  // 14
  	initflag = DQ;     // initflag等于1初始化失败
  	Delay_OneWire(5);   //适当延时保证时序完整
  
  	return initflag;
}

2.通过单总线向DS18B20写一个字节

注意 :传输数据低位在前面
在这里插入图片描述
写周期开始的时候,主机先把总线拉低大于1us表示写周期的开始。
若主机写0,则继续拉低电平最少60us直到写周期结束,然后释放总线为高电平
若主机写1,在拉低总线电平1us后,释放总线为高电平,直到写周期结束。

void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;				    //主机拉低总线开始写
		DQ = dat&0x01;		    //数据传输 低位在前 去最低置兼延时
		Delay_OneWire(5);	    //使从机有时间去取到该位置
		DQ = 1;				    //送完当前位后释放总线
		dat >>= 1;			    // 为送入下一位做准备
		                        //注意:左移还是右移,先移还是后移
	}
	Delay_OneWire(5);

}

3.从DS18B20读取一个字节

读周期开始的时候,主机先把总线拉低大于1us,然后释放总线。主机释放总线后:
若主机发送0,则继续拉低总线并保持至少从读周期开始15us,然后释放总线为高电平。
若主机发送1,则在主机释放总线后不拉低总线,为高电平。
主机必须在读周期开始的15us内检测总线电平的高低
在这里插入图片描述

unsigned char Read_DS18B20(void)	//调用返回读取的字节
{
	unsigned char i;			    //能用局部变量就不用全局变量
	unsigned char dat;
//	unsigned char index = 0;
  	   	
	for(i=0;i<8;i++)		    //每次读一位
	{
		DQ = 0;				   //主机拉低总线至少一微秒开始读当前位
		dat >>= 1;			   //位移兼延时,第一次右移位 无作用
		DQ = 1; 			   //主机释放总线
	   	Delay_us();			   //延时 使得从机得到响应

		if(DQ)  			   //如果检测到了1  或写成(DQ==1)
		{
			dat |= 0x80;	   //将 dat 置于最高位  1000 1000
		}	    
		Delay_OneWire(5);		//适当延时,度周期至少60US
	}
	return dat;					//将接收好的字节反送给调用处
}

4.DS18B20温度采集程序

unsigned char rd_temperature(void)
{
   char temp,flag,xiaoshu1,xiaoshu2;
   int low,high;
   init_ds18b20();
   Write_DS18B20(0xcc);			//跳过写rom指令
   Write_DS18B20(0x44);			//启动温度转换
   Delay_OneWire(50);  			

   init_ds18b20();
   Write_DS18B20(0xcc);			//跳过写rom指令
   Write_DS18B20(0xbe);			//启动温度转换	转换期间必须10us(最多) 给单总线强上拉
   Delay_OneWire(50);  

   low=Read_DS18B20();  	 //传输过程中 先是低八位传输  后是 高八位传输
   high=Read_DS18B20();

   temp=low/16+high*16 ;  //温度组装成为字节
                          //相当于 temp=(low>>4)|(high<<4)	;低字节右移四位  高字节左移
   if(temp>=127)		  //符号位是1,则结果是负   此处判断标志位
   {
 		flag = 1; 		 //若符号位是1,则 温度为负数
		temp = ~temp+1;  //补码转换为原码
   
   }
   xiaoshu1 = (low&0x0f)*10/16;       //取出温度第一位小数
   xiaoshu2 = (low&0x0f)*100/16%10;   //取出温度第二位小数
   //另外一种写法
   /*
   xiaoshu1 = (low&0x0f)*625/1000;
   xiaoshu2 = (low&0x0f)*625/100%10;
   */
   return temp;
}
/CCH 跳过rom指令 则 1100 1100 则写入的时候 0011 0011
//BEH  写的时候低位前,高位后  1011 1110 则送进寄存器的段码是0111 1101
// 8421 a 10 1010  b 11 1011   c 12 1100   d 13 1101   e 14 1110   f 15 1111

5.延时子函数

void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}

void Delay_us(void)
{
	unsigned char i;
	i = 30;
	while (--i);
}

希望可以对你有所帮助。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值