目录
【经验分享】STM32实例-DS18B20温度传感器实验②-DS18B20读取温度
一、单总线温度传感器DB18B20简介
1.1简介:
单总线温度传感器DS18B20是一种数字温度传感器,由Maxim Integrated公司生产。它采用了一种称为“1-Wire”的通信协议,这意味着多个传感器可以通过同一根总线进行通信,并且每个传感器都有唯一的64位序列号,使其能够在同一总线上被唯一地识别。DS18B20具有较高的精度和可靠性,能够以数字形式输出温度数据,其工作温度范围广泛,通常为-55°C至+125°C。此外,DS18B20还具有低功耗特性,可通过简单的3线接口与微控制器或其他数字设备进行通信,因此在各种应用中被广泛采用,如温度监控、气象站、电子设备温度管理等。
1.2特性:
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.告警搜索命令识别和寻址温度在编定的极限之外的器件(温度告警情况)
11.应用范围包括恒温控制,工业系统,消费类产品,温度计或任何热敏系统
1.3引脚排列
引脚说明:
二、信号时序介绍和硬件设计
2.1初始化时序
![](https://img-blog.csdnimg.cn/direct/1dcfa42602a841e4980789202bc7f71f.png)
2.2写时序
2.3读时序
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要 60us,且在 2 次独立的读时序之间至少需要 1us 的恢复时间。每个读时序都由主机发起,至少拉低总线 1us。主机在读时序期间必须释放总线,并且在时序起始后的 15us 之内采样总线状态。读时序图如下:
2.4硬件设计:
从电路图中可以看到,单总线接口连接在 STM32F1 芯片的 PG11管脚上,并且接了一个 10K 的上拉电阻。通过 PG11 管脚模拟单总线时序与 DS18B20 温度传感器通信。由于开发板标配是不带 DS18B20 温度传感器的,开发板上只提供接口DS1,所以做本章实验,大家需要准备一个 DS18B20 传感器插在预留的接口上,一定要注意温度传感器的方向,在接口处我们已经用丝印画了一个凸起,所以只需要将温度传感器对应插入即可。
三、汇编代码
3.1通信时序实现:
void WR_Bit(bit i)
{
DQ=0;//产生写时序
_nop_();
_nop_();//总线拉低持续时间要大于1us
DQ=i;//写数据 ,0和1均可
Delayxus_DS18B20(3);//延时60us,等待ds18b20采样读取
DQ=1;//释放总线
}
void WR_Byte(unsigned char dat)
{
unsigned char i="0";
while(i++<8)
{
WR_Bit(dat&0x01);//从最低位写起
dat>>=1; //注意不要写成dat>>1
}
}
unsigned char Read_Bit()
{
unsigned char ret;
DQ=0;//拉低总线
_nop_(); _nop_();
DQ=1;//释放总线
_nop_(); _nop_();
_nop_(); _nop_();
ret=DQ;//读时隙产生7 us后读取总线数据。把总线的读取动作放在15us时间限制的后面是为了保证数据读取的有效性
Delayxus_DS18B20(3);//延时60us,满足读时隙的时间长度要求
DQ=1;//释放总线
return ret; //返回读取到的数据
}
unsigned char Read_Byte()
{
unsigned char i;
unsigned char dat="0";
for(i=0;i<8;i++)
{
dat>>=1;//先读最低位
if(Read_Bit())
dat|=0x80;
}
return(dat);
}
3.2在Keil中代码实现:
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define out P0 //这行定义了out为P0端口。
sbit smg1=out^4;
sbit smg2=out^5; //两行定义了smg1和smg2为P0端口的第4位和第5位。
sbit DQ=P3^7;
void delay5(uchar);
void init_ds18b20(void);
uchar readbyte(void);
void writebyte(uchar);
uchar retemp(void);//这几行是函数声明,分别用于延时、初始化DS18B20、读取字节、写入字节、读取温度。
void main(void)
{
uchar i,temp;
delay5(1000);
while(1)
{
temp=retemp(); //
for(i=0;i<10;i++) //lѸɨĨ˽ëڜ10Վ
{
out=(temp/10)&0x0f;
smg1=0;
smg2=1;
delay5(1000); //ғʱ5ms
out=(temp%10)&0x0f;//将温度的个位数取出并存储在P0端口的低四位。
smg1=1;
smg2=0;
delay5(1000); //ғʱ5ms
}
}
}
/*--------------ޫȷғʱ5usؓԌѲ---------*/
void delay5(uchar n)
{
do
{
_nop_();
_nop_();
_nop_();
n--;
}
while(n);
}
/*--------------Եʼۯگ˽--------------------*/
void init_ds18b20(void)
{
uchar x=0;
DQ =0;
delay5(120);
DQ =1;
delay5(16);
delay5(80);
}
/*--------------ׁȡһؖޚگ˽----------------*/
uchar readbyte(void)
{
uchar i=0;
uchar date=0;
for (i=8;i>0;i--)
{
DQ =0;
delay5(1);
DQ =1; //15īŚ-ˍП
date>>=1;
if(DQ)
date|=0x80;
delay5(11);
}
return(date);
}
/*--------------дһؖޚگ˽------------------*/
void writebyte(uchar dat)
{
uchar i=0;
for(i=8;i>0;i--)
{
DQ =0;
DQ =dat&0x01;//д"1" ՚15īŚ-֍
delay5(12); //д"0" -֍60ī
DQ = 1;
dat>>=1;
delay5(5);
}
}
/*--------------ׁȡςگ˽------------------*/
uchar retemp(void)//读取温度函数,通过DS18B20传感器获取温度数据并转换为摄氏度。
{
uchar a,b,tt;
uint t;
init_ds18b20();
writebyte(0xCC);
writebyte(0x44);
init_ds18b20();
writebyte(0xCC);
writebyte(0xBE);
a=readbyte();
b=readbyte();
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
return(tt);
}
3.3Keil中观察时序图:
操作1:
操作2:
操作3:
操作4,点击RUN
查看波形图:
点击X停止
四、仿真+实验
4.1仿真:
要求:
使用51单片机的一个 IO 口模拟单总线时序与温度传感器DS18B20通信,将检测的环境温度读取出来。
在Proteus中画出仿真图:
导入生成HEX文件:
结果为:
温度检测仿真
4.2烧录到普中开发板上:
五、总结:
本次学习主要针对DB18B20单总线温度传感器进行了系统和细致的学习与了解,对温度传感器有了进一步的了解,对于以后项目中添加温度识别模块起到了非常重要的作用,同时不断加强对51单片机的了解,嵌入式开发更进一步。
由于本人才疏学浅,文章中提到内容可能会出现错误,如若有错误,还望大家批评指正!感谢阅读。
参考文献: