《嵌入式硬件(四):温度传感器DS1820》

一、DS1820的引脚

DS1820单总线数字温度计:异步串行半双工

特性:

1)独特的单线接口,只需 1 个接口引脚即可通信

2)多点(multidrop)能力使分布式温度检测应用得以简化

3)不需要外部元件

4)可用数据线供电

5)不需备份电源

6)测量范围从 - 55℃至 + 125℃,增量值为 0.5℃。等效的华氏温度范围是 - 67°F 至 257°F,增量值为 0.9°F

7)以 9 位数字值方式读出温度

8)在 1 秒(典型值)内把温度变换为数字

9)用户可定义的,非易失性的温度告警设置

10)告警搜索命令识别和寻址温度在编定的极限之外的器件(温度告警情况)

应用范围包括恒温控制,工业系统,消费类产品,温度计或任何热敏系统

51单片机和DS1820是线与关系,数据接受方需要释放总线->电平的高低由对方决定

上拉电阻通常在4.7k~10k,双方在释放总线时,保证线是高电平

二、ROM操作命令

  • Read ROM (读 ROM) [33h]:允许总线主机读 DS1820 的 8 位产品系列编码、唯一的 48 位序列号,以及 8 位的 CRC。仅能在总线上仅有一个 DS1820 时使用;若存在多个从属器件,所有从片同时发送会发生数据冲突(漏极开路产生 "线与" 结果)。

  • Match ROM ("符合" ROM) [55h]:命令后紧跟 64 位 ROM 数据序列,允许总线主机对多点总线上特定的 DS1820 寻址。只有与 64 位 ROM 序列严格相符的 DS1820,才会对后继存贮器操作命令响应;不符的从片会等待复位脉冲。总线上有单个或多个器件时都可使用。

  • Skip ROM ("跳过" ROM) [0Ch]:在单点总线系统中,允许总线主机不提供 64 位 ROM 编码就访问存储器操作,以此节省时间。若总线上有多个从属器件,且在该命令后发读命令,多个从片同时发数据会引发总线数据冲突(漏极开路下拉产生 "线与" 效果)。

  • Search ROM (搜索 ROM) [F0h]:系统刚工作时,总线主机可能不清楚单线总线上的器件个数或 64 位 ROM 编码。此命令允许主机用 "消去"(elimination) 处理,识别总线上所有从片的 64 位 ROM 编码。

  • Alarm Search (告警搜索) [ECh]:流程与 "搜索 ROM" 命令相同,但仅当 DS1820 最近一次温度测量出现告警(温度高于 TH 或低于 TL)时,才会对此命令响应。DS1820 上电后,告警条件会保持,直到温度测量显示非告警值,或修改 TH/TL 设置使测量值回到允许范围;EEPROM 内的触发器值用于告警。

三、DS1820的寄存器

  • 读暂存存储器(Read Scratchpad)[BEh]:读取暂存存储器内容,从字节 0 开始,直到字节 8(CRC);若并非所有位置都可读,主机可随时发复位中止读操作。
  • 复制暂存存储器(Copy Scratchpad)[48h]:将暂存存储器内容复制到 DS1820 的 E² 存储器,把温度触发器字节存入非易失性存储器;若总线主机发此命令后读时间片,DS1820 在复制时总线输出 "0",完成后输出 "1";若为寄生电源供电,主机发命令后需立即强制上拉至少 10ms。
  • 温度变换(Convert T)[44h]:启动温度变换,无需额外数据;若总线主机发此命令后读时间片,DS1820 变换时总线输出 "0",完成后输出 "1";若为寄生电源供电,主机发命令后需立即强制上拉至少 2 秒。
  • 重新调出 E2(Recall E2)[B8h]:把 E² 中温度触发器的值调回暂存存储器(器件上电时也会自动执行该操作,所以上电后暂存存储器就有有效数据);发此命令后,第一个读数据时间片,器件输出 "0" 表示 "忙","1" 表示 "准备就绪"。
  • 读电源(Read Power Supply)[B4h]:发此命令后,第一个读出数据的时间片,器件会给出电源方式信号:"0" 表示寄生电源供电,"1" 表示外部电源供电。

四、DS1820的时序图

1.初始化(检测芯片是否能用)

方法:先给51单片机低电平,如果可以检测到一个低电平,一个高电平,芯片就是好的

cs 复制代码
#include <reg52.h>
#include <intrins.h>

#define DS18B20_SET		(P3 |= (1 << 7))   //拉高
#define DS18B20_CLEAR 	(P3 &= ~(1 << 7))  //拉低
#define DS18B20_TST	 	((P3 & (1 << 7)) != 0)	//判断 高电平


void Delay10us(unsigned int n)	//@12.000MHz
{
 	unsigned char data i;

 	_nop_();
 	_nop_();
 	_nop_();
 	i = 2 * n;
 	while (--i)
 	{
 		_nop_();
 	}
}

int reset_ds18b20(void)
{
	int t = 0;
	DS18B20_CLEAR;
	Delay10us(50);
	DS18B20_SET;
	Delay10us(2);
	while(DS18B20_TST && t < 25)
	{
	 	Delay10us(1);
		++t;
	}
	if(t >= 25)
	{
		return 0;
	}

	t = 0;
	while(!DS18B20_TST && t < 20)
	{
		Delay10us(1);
		++t;
	}
	if(t >= 20)
	{
		return 0;
	}
	return 1;
}


int main(void)
{
	int t = reset_ds18b20();
	if(1 == t)
	{
		P2 = 0;
	}
	else
	{
		P2 = 0xFF;
	}
 	while(1)
	{

	}
	return 0;
}

温度读取

main.c

cs 复制代码
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include <string.h>
#include "uart.h"
#include "delay.h"
#include "ds18b20.h"


int main(void)
{	
	xdata char s[24];
	init_uart();
	while(1)
	{
		float f;
		f = get_temperatuer();
		sprintf(s, "%f", f);
		send_buffer(s, strlen(s));
	}
	return 0;
}

delay.c

cs 复制代码
#include "delay.h"
#include <intrins.h>
void delay(unsigned int n)//0~65526
{
	while(n--);
}

void Delay10us(unsigned int n)	//@12.000MHz
{
	unsigned char data i;
	
	_nop_();
	_nop_();
	_nop_();
	i = 2 * n;
	while (--i)
	{
		_nop_();
	}
}

void delay_1ms(unsigned int n)
{
	while(n--)
	{
		 Delay10us(100);
	}
}

ds18b20.c

cs 复制代码
 #include <reg52.h>
#include <intrins.h>
#include "delay.h"
#include "ds18b20.h"

static int reset_ds18b20(void)
{
	int t;
	DS18B20_CLEAR;
	Delay10us(70);
	DS18B20_SET;
	Delay10us(4);

	t = 0;
	while(DS18B20_TST && t < 30)
	{
		Delay10us(1);
		++t;
	}
	if(t >= 30)
	{
		return 0;
	}

	t = 0;
	while(!DS18B20_TST && t < 30)
	{
		Delay10us(1);
		++t;
	}
	if(t >= 30)
	{
		return 0;
	}
	return 1;
}

void ds18b20_write(unsigned char n)	//0x01010 110 & 0000 0001
{
	int i;
	for(i = 0;i < 8;++i)
	{
		if(n & 0x01) // 1
		{
			DS18B20_CLEAR;
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			DS18B20_SET;
			Delay10us(5);				
		}
		else
		{
		 	DS18B20_CLEAR;
			Delay10us(6);
			DS18B20_SET;
		}
		n >>= 1;	
	}
}

unsigned char ds18b20_read(void)
{
	unsigned char ret = 0;
	int i;
	for(i = 0;i < 8;++i)
	{
		DS18B20_CLEAR;
		_nop_();
		_nop_();
		DS18B20_SET;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		if(DS18B20_TST)
		{
			ret |= 1 << i;	
		}
		Delay10us(5);							
	}
	return ret;
}

float get_temperatuer(void)
{
	unsigned char tl, th;
	short t;
	reset_ds18b20();
	ds18b20_write(0xCC);
	ds18b20_write(0x44);
	delay_1ms(750);
	reset_ds18b20();
	ds18b20_write(0xCC);
	ds18b20_write(0xBE);
	tl = ds18b20_read();
	th = ds18b20_read();
	t = tl;
	t |= th << 8;
	return t * 0.0625;
}

uart.c

cs 复制代码
#include "uart.h"
#include <reg52.h>

xdata char rcv_buffer[64] = {0};
int pos = 0;

void init_uart(void)
{
	unsigned char t;
	t = SCON;
	t &= ~(3 << 6);
	t |= (1 << 6) | (1 << 4);
	SCON = t;

	PCON |= (1 << 7);
	
	IE |= (1 << 7) | (1 << 4);

	t = TMOD;
	t &= ~(3 << 4);
	t |= (2 << 4);
	t &= ~(3 << 6);
	TMOD = t;
	TH1 = 204; //12MHz
	TL1 = 204;
	TCON |= (1 << 6);
}


void uart_handler(void) interrupt 4
{
	 if((SCON & (1 << 0)) != 0)
	 {
	 	rcv_buffer[pos++] = SBUF;
		SCON &= ~(1 << 0);
	 }
}

void send_char(char ch)
{
	SBUF = ch;
	while((SCON & (1 << 1)) == 0);
	SCON &= ~(1 << 1);
}

void send_buffer(const char *p, int len)
{
	while(len--)
	{
		send_char(*p++);
	}	
}
相关推荐
三之又三7 小时前
PowerPMAC配置EtherCAT设备
嵌入式硬件·cnc·powerpmac
朝颜_祝余7 小时前
在电路浪涌测试中,TVS(瞬态电压抑制二极管)的防护效果确实会受到陪测设备中去耦网络(Decoupling Network,DN)的显著影响
单片机·嵌入式硬件
mei_you_n8 小时前
JLINK 调试器单步调试单片机
单片机·嵌入式硬件
HIZYUAN8 小时前
AG32 ( MCU+FPGA二合一 )是如何卷入了三相电能计量市场的
单片机·嵌入式硬件
pengfei_M9 小时前
四、FVP启动linux
linux·单片机·嵌入式硬件
weixin_471525789 小时前
【ARMday02】
单片机·嵌入式硬件
世微 如初11 小时前
无需外部补偿的同步降压方案:AP3471在分布式供电系统中的应用
单片机·嵌入式硬件·芯片·led驱动·led电源驱动
云山工作室11 小时前
基于单片机的声光控制楼道灯(论文+源码)
单片机·嵌入式硬件
humingling11 小时前
单片机的bin、exe、elf、hex文件差异
单片机·嵌入式硬件