【常用传感器】DS18B20温度传感器原理详解及例程代码_ds18b20温度传感器工作原理

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 4.DS18B20拉低电平60~240us之后,会释放总线。
    在这里插入图片描述
    代码如下:
/\*\*\*\*\*初始化DS18B20\*\*\*\*\*/
unsigned int Init\_DS18B20(void)
{
  unsigned int x=0;
  DQ = 1;      //DQ复位
  delay(4);    //稍做延时
  DQ = 0;      //单片机将DQ拉低
  delay(60);   //精确延时,大于480us
  DQ = 1;      //拉高总线
  delay(8);
  x = DQ;      //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  delay(4);
  return x;
}

2.写时序

总线控制器通过控制单总线高低电平持续时间从而把逻辑1或0写DS18B20中。每次只传输1位数据

单片机想要给DS18B20写入一个0时,需要将单片机引脚拉低,保持低电平时间要在60~120us之间,然后释放总线
单片机想要给DS18B20写入一个1时,需要将单片机引脚拉低,拉低时间需要大于1us,然后在15us内拉高总线.

在写时序起始后15μs到60μs期间,DS18B20处于采样单总线电平状态。如果在此期间总线为高电平,则向DS18B20写入1;如果总线为低电平,则向DSl8B20写入0。

注意:2次写周期之间至少间隔1us

在这里插入图片描述

/\*\*\*\*\*写一个字节\*\*\*\*\*/
void WriteOneChar(unsigned char dat)
{
  unsigned char i=0;
  for (i=8; i>0; i--)
  {
    DQ = 0;
    DQ = dat&0x01;  //与1按位与运算,dat最低位为1时DQ总线为1,dat最低位为0时DQ总线为0
	delay(4);
    DQ = 1;
    dat>>=1;
  }
  delay(4);
}


DS18B20写入的功能命令:

ROM指令:

采用多个DS18B20时,需要写ROM指令来控制总线上的某个DS18B20
如果是单个DS18B20,直接写跳过ROM指令0xCC即可
在这里插入图片描述

RAM指令,DS18B20的一些功能指令

常用的是:

温度转换 0x44

开启温度读取转换,读取好的温度会存储在高速暂存器的第0个和第一个字节中

读取温度 0xBE
读取高速暂存器存储的数据
在这里插入图片描述

读时序

读时隙由主机拉低总线电平至少1μs然后再释放总线,读取DS18B20发送过来的1或者0

DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。

在这里插入图片描述
注意:所有读时隙必须至少需要60us,且在两次独立的时隙之间至少需要1ps的恢复时间

同时注意:主机只有在发送读暂存器命令(0xBE)或读电源类型命令(0xB4)后,立即生成读时隙指令,DS18B20才能向主机传送数据。 也就是先发读取指令,再发送读时隙

最后一点: 写时序注意是先写命令的低字节,比如写入跳过ROM指令0xCC(11001100),写的顺序是“零、零、壹、壹、零、零、壹、壹”,

读时序时是先读低字节,在读高字节,也就是先读取高速暂存器的第0个字节(温度的低8位),在读取高速暂存器的第1个字节(温度的高8位) 我们正常使用DS18B20读取温度读取两个温度字节即可

51例程
sbit DQ=P1^0;	//定义DS18b20的管脚

/\*\*\*\*\*延时子程序\*\*\*\*\*/
void delay(unsigned int t)
{
	for(;t>0;t--);
}


/\*\*\*\*\*初始化DS18B20\*\*\*\*\*/
unsigned char Init\_DS18B20(void)
{
  unsigned char x=0;
  DQ = 1;      //DQ复位
  delay(8);    //稍做延时
  DQ = 0;      //单片机将DQ拉低
  delay(80);   //精确延时,大于480us
  DQ = 1;      //拉高总线
  delay(8);
  x = DQ;      //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  delay(4);
  return x;
}

/\*\*\*\*\*读一个字节\*\*\*\*\*/
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(4);
  }
  return(dat);
}

/\*\*\*\*\*写一个字节\*\*\*\*\*/
void WriteOneChar(unsigned char dat)
{
  unsigned char i=0;
  for (i=8; i>0; i--)
  {
    DQ = 0;
    DQ = dat&0x01;
	delay(4);
    DQ = 1;
    dat>>=1;
  }
  delay(4);
}

/\*\*\*\*\*读取温度\*\*\*\*\*/
int ReadTemperature(void)
{
  	unsigned char a=0;
  	unsigned char b=0;
  	unsigned int t=0;
  	t=Init\_DS18B20();
  	if(t) return Real_temp;
  	WriteOneChar(0xCC);  //跳过读序号列号的操作
  	WriteOneChar(0x44);  //启动温度转换
  	t=Init\_DS18B20();
  	if(t) return Real_temp;
  	WriteOneChar(0xCC);  //跳过读序号列号的操作
  	WriteOneChar(0xBE);  //读取温度寄存器
  	a=ReadOneChar();     //读低8位
  	b=ReadOneChar();     //读高8位
  	t=b;
  	t<<=8;
  	t=t|a;
  	if(t<=0||t>0x900) 
	return Real_temp;
	t=t\*0.625+0.5;
  	return(t);
}


STM32例程

DS18B20.C

#include "ds18b20.h"
#include "delay.h" 

//复位DS18B20
void DS18B20\_Rst(void)	   
{                 
	DS18B20\_IO\_OUT(); 	//SET PG11 OUTPUT
    DS18B20_DQ_OUT=0; 	//拉低DQ
    delay\_us(750);    	//拉低750us
    DS18B20_DQ_OUT=1; 	//DQ=1 
	delay\_us(15);     	//15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20\_Check(void) 	   
{   
	u8 retry=0;
	DS18B20\_IO\_IN();	//SET PG11 INPUT 
    while (DS18B20_DQ_IN&&retry<200)
	{
		retry++;
		delay\_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
	{
		retry++;
		delay\_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20\_Read\_Bit(void) 	 
{
    u8 data;
	DS18B20\_IO\_OUT();	//SET PG11 OUTPUT
    DS18B20_DQ_OUT=0; 
	delay\_us(2);
    DS18B20_DQ_OUT=1; 
	DS18B20\_IO\_IN();	//SET PG11 INPUT
	delay\_us(12);
	if(DS18B20_DQ_IN)data=1;
    else data=0;	 
    delay\_us(50);           
    return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20\_Read\_Byte(void)     
{        
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20\_Read\_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20\_Write\_Byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
	DS18B20\_IO\_OUT();	//SET PG11 OUTPUT;
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            DS18B20_DQ_OUT=0;	// Write 1
            delay\_us(2);                            
            DS18B20_DQ_OUT=1;
            delay\_us(60);             
        }
        else 
        {
            DS18B20_DQ_OUT=0;	// Write 0
            delay\_us(60);             
            DS18B20_DQ_OUT=1;
            delay\_us(2);                          
        }
    }
}
//开始温度转换
void DS18B20\_Start(void) 
{   						               
    DS18B20\_Rst();	   
	DS18B20\_Check();	 
    DS18B20\_Write\_Byte(0xcc);	// skip rom
    DS18B20\_Write\_Byte(0x44);	// convert
} 

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在 
u8 DS18B20\_Init(void)
{
 	GPIO_InitTypeDef  GPIO_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);    //输出1

	DS18B20\_Rst();

	return DS18B20\_Check();
}  
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20\_Get\_Temp(void)
{
    u8 temp;
    u8 TL,TH;
	short tem;
    DS18B20\_Start ();  			// ds1820 start convert
    DS18B20\_Rst();
    DS18B20\_Check();	 
    DS18B20\_Write\_Byte(0xcc);	// skip rom
    DS18B20\_Write\_Byte(0xbe);	// convert 
    TL=DS18B20\_Read\_Byte(); 	// LSB 
    TH=DS18B20\_Read\_Byte(); 	// MSB 
	    	  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;					//温度为负 
    }else temp=1;				//温度为正 
    tem=TH; 					//获得高八位
    tem<<=8;    
    tem+=TL;					//获得底八位
    tem=(float)tem\*0.625;		//转换 
	if(temp)return tem; 		//返回温度值
	else return -tem;    
}



DS18B20.H

#ifndef \_\_DS18B20\_H
#define \_\_DS18B20\_H 
#include "sys.h" 

//IO方向设置
#define DS18B20\_IO\_IN() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}
#define DS18B20\_IO\_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}
IO操作函数 
#define DS18B20\_DQ\_OUT PGout(11) //数据端口 PA0 
#define DS18B20\_DQ\_IN PGin(11) //数据端口 PA0 
   	
u8 DS18B20\_Init(void);//初始化DS18B20
short DS18B20\_Get\_Temp(void);//获取温度
void DS18B20\_Start(void);//开始温度转换
void DS18B20\_Write\_Byte(u8 dat);//写入一个字节
u8 DS18B20\_Read\_Byte(void);//读出一个字节
u8 DS18B20\_Read\_Bit(void);//读出一个位
u8 DS18B20\_Check(void);//检测是否存在DS18B20
void DS18B20\_Rst(void);//复位DS18B20 
#endif


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

oid);//读出一个位
u8 DS18B20_Check(void);//检测是否存在DS18B20
void DS18B20_Rst(void);//复位DS18B20
#endif




[外链图片转存中...(img-UJ8uuDew-1715708930650)]
[外链图片转存中...(img-JHEQYFxM-1715708930651)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于STM32的DS18B20温度传感器例程: 1. 首先,你需要连接DS18B20到STM32,可以参考DS18B20数据手册来连接。一般来说,你需要将DS18B20的VCC接到STM32的5V引脚,将GND接到GND引脚,将DQ(数据线)接到STM32的GPIO引脚。 2. 接下来,在你的STM32项目中,你需要包含以下库文件: ``` #include "stm32f10x.h" #include "delay.h" #include "ds18b20.h" ``` 其中,"delay.h"是提供延时函数的头文件,"ds18b20.h"是DS18B20的头文件。 3. 在主函数中,你需要初始化GPIO引脚和DS18B20: ``` int main(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // DQ引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 最大输出速度50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB0 ds18b20_init(); // 初始化DS18B20 while(1) { // 在这里读取DS18B20的温度并进行其他处理 } } ``` 4. 接下来,在"ds18b20.h"头文件中,你需要定义以下常量和函数: ``` #define DS18B20_PORT GPIOB // DS18B20使用的GPIO端口 #define DS18B20_PIN GPIO_Pin_0 // DS18B20使用的GPIO引脚 void ds18b20_init(void); void ds18b20_write_byte(uint8_t byte); uint8_t ds18b20_read_byte(void); float ds18b20_get_temp(void); ``` 其中,"ds18b20_init"函数用于初始化DS18B20,"ds18b20_write_byte"和"ds18b20_read_byte"函数用于向DS18B20写入字节并从DS18B20读取字节,"ds18b20_get_temp"函数用于获取DS18B20的温度。 5. 最后,在"ds18b20.c"文件中,你需要实现以上函数: ``` #include "ds18b20.h" void ds18b20_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 开漏输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); // 初始化DS18B20引脚 GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); // 初始化时,DQ引脚输出高电平 } void ds18b20_write_byte(uint8_t byte) { uint8_t i; for(i = 0; i < 8; i++) { GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN); // 先将DQ引脚拉低 delay_us(2); // 延时2us if(byte & 0x01) // 根据byte的最低位来决定输出高电平还是低电平 GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); delay_us(60); // 延时60us GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); // 将DQ引脚拉高 delay_us(2); // 延时2us byte >>= 1; // 将byte右移一位,继续处理下一位 } } uint8_t ds18b20_read_byte(void) { uint8_t i, byte = 0; for(i = 0; i < 8; i++) { GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN); // 先将DQ引脚拉低 delay_us(2); // 延时2us GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); // 将DQ引脚拉高 delay_us(2); // 延时2us byte >>= 1; // 先将byte右移一位 if(GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN)) // 判断DQ引脚是否为高电平 byte |= 0x80; // 如果是,则将byte最高位置为1 delay_us(60); // 延时60us } return byte; } float ds18b20_get_temp(void) { uint8_t temp_l, temp_h; float temp; ds18b20_write_byte(0xcc); // 跳过ROM操作 ds18b20_write_byte(0x44); // 启动温度转换 delay_ms(750); // 等待转换完成(DS18B20最长转换时间为750ms) ds18b20_write_byte(0xcc); // 跳过ROM操作 ds18b20_write_byte(0xbe); // 读取温度寄存器 temp_l = ds18b20_read_byte(); // 先读取温度低8位 temp_h = ds18b20_read_byte(); // 再读取温度高8位 temp = (float)(temp_h << 8 | temp_l) / 16; // 将温度高8位和低8位合并并转换成浮点数 return temp; } ``` 以上就是基于STM32的DS18B20温度传感器例程,希望对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值