简介
DS18B20采用的是单总线的接线方式,只用一条线与单片机进行数据的输入和输出,具有经济性好,抗干扰能力强等优点。测量的温度范围是-55℃到125℃。在使用DS18B20的时候,输入输出引脚要接一个上拉电阻,这里接的是10K的上拉电阻,上拉电阻用于在总线不使用时保持线路处于高电平状态,DS18B20传感器测量的温度值将存储在传感器内部的一个2字节寄存器中。VDD可接3.3V-5V的电源。
DS18B20返回的16位二进制数代表此刻探测的温度值,其高五位代表正负。如果高五位全部为1,则代表返回的温度值为负值。如果高五位全部为0,则代表返回的温度值为正值。后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值,我们的程序里是乘的0.625,也就是扩大了十倍,这样就可以在显示的时候可以有小数部分,更能准确地看到温度的变化。
软件流程图
51单片机的流程图
STM32单片机的流程图
程序分析
51单片机中的DS18B20程序
ds18b20.c
/**********************************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
**********************************/
/**********************************
包含头文件
**********************************/
#include "ds18b20.h"
/****
*******延时函数
*****/
void ds18b20_delay_uint(uint z)
{
while(z--);
}
/****
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
* 函数功能: DS18B20初始化函数
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
****/
void Ds18b20_Init(void)
{
bit q;
DS18B20_DQ=1; //把总线拿高
ds18b20_delay_uint(1); //15us
DS18B20_DQ=0; //给复位脉冲
ds18b20_delay_uint(80); //750us
DS18B20_DQ=1; //把总线拿高 等待
ds18b20_delay_uint(10); //110us
q=DS18B20_DQ; //读取18b20初始化信号
ds18b20_delay_uint(20); //200us
DS18B20_DQ=1; //把总线拿高 释放总线
}
/*****
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
* 函数功能: 写ds18b20内的数据函数
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*****/
void write_18b20(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{ //写数据是低位开始
DS18B20_DQ=0; //把总线拉低写时间隙开始
DS18B20_DQ=dat&0x01; //向18b20总线写数据了
ds18b20_delay_uint(5); // 60us
DS18B20_DQ=1; //释放总线
dat>>=1;
}
}
/*****
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
* 函数功能: 读取ds18b20内的数据函数
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*****/
uchar read_18b20(void)
{
uchar i,value;
for(i=0;i<8;i++)
{
DS18B20_DQ=0; //把总线拿低读时间隙开始
value>>= 1; //读数据是低位开始
DS18B20_DQ=1; //释放总线
if(DS18B20_DQ==1) //开始读写数据
value|=0x80;
ds18b20_delay_uint(5); //60us 读一个时间隙最少要保持60us的时间
}
return value; //返回数据
}
/*****
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
* 函数功能: 读取温度值函数
* 输入参数: 无
* 返 回 值: 温度值(扩大10倍)
* 说 明:无
*****/
uint Ds18b20_Read_Temp(void)
{
uint value;
uchar low; //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
Ds18b20_Init(); //初始化18b20
write_18b20(0xcc); //跳过64位ROM
write_18b20(0x44); //启动一次温度转换命令
ds18b20_delay_uint(50); //500us
Ds18b20_Init(); //初始化18b20
write_18b20(0xcc); //跳过64位ROM
write_18b20(0xbe); //发出读取暂存器命令
low=read_18b20(); //读温度低字节
value=read_18b20(); //读温度高字节
value<<=8; //把温度的高位左移8位
value|=low; //把读出的温度低位放到value的低八位中
value*=0.625; //转换到温度值 小数
return value; //返回读出的温度 带小数
}
ds18b20.h
/**********************************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
**********************************/
#ifndef __DS18B20_H__
#define __DS18B20_H__
/**********************************
包含头文件
**********************************/
#include "main.h"
/**********************************
PIN口定义
**********************************/
sbit DS18B20_DQ=P2^0; //ds18b20数据引脚P3.7
/**********************************
函数声明
**********************************/
uint Ds18b20_Read_Temp(void); //读取温度值函数
#endif
STM32单片机中的DS18B20程序-HAL库
ds18b20.c
/**********************************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
**********************************/
/**********************************
包含头文件
**********************************/
#include "./HAL/ds18b20/ds18b20.h"
#include "./HAL/delay/delay.h"
unsigned char ds_cnt=0;//ds18b20 读取存在脉冲超时计数
/****
*******DS18B20引脚初始化函数
*****/
void Ds18b20_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
DQ_GPIO_CLK_ENABLE();
/*Configure GPIO pin : DQ_Pin */
GPIO_InitStruct.Pin = DQ_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DQ_GPIO_Port, &GPIO_InitStruct);
}
/****
*******DS18B20初始化函数
*****/
void DS_rest(void)
{
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_SET);//D=1;
delay_us(1);
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_RESET);//D=0;
delay_us(750);
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_SET);//D=1;
delay_us(100);
while(HAL_GPIO_ReadPin(DQ_GPIO_Port,DQ_Pin))
{
delay_us(1);
ds_cnt++;
if(ds_cnt==200)
{
ds_cnt=0;
break;
}
}
delay_us(300); //200us
}
/****
*******写ds18b20内的数据函数
*****/
void write_byte(uint8_t dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_SET);//D=1;
delay_us(1);
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_RESET);//D=0;
delay_us(2);
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin,(GPIO_PinState)(dat&0x01));//D=dat&0x01;
delay_us(30);
dat=dat>>1;
}
}
/****
*******读取ds18b20内的数据函数
*****/
unsigned char read_byte(void)
{
unsigned char i,dat,tmp=0;
for(i=0;i<8;i++)
{
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_SET);//D=1;
delay_us(1);
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_RESET);//D=0;
delay_us(2);
HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_SET);//D=1;
delay_us(2);
dat=HAL_GPIO_ReadPin(DQ_GPIO_Port,DQ_Pin);//dat=D;
tmp|=(dat<<i);
delay_us(30);
}
return tmp;
}
/****
*******读取温度值函数
*******返回值:温度值(扩大10倍)
*****/
unsigned int Ds18b20_Read_Temp(void)
{
unsigned char i,j;
unsigned int tem=0;
DS_rest();
write_byte(0xcc);
write_byte(0x44);
DS_rest();
write_byte(0xcc);
write_byte(0xbe);
i=read_byte();
j=read_byte();
tem|=j&0x0F;
tem<<=8;
tem|=i;
tem=(tem*0.625);
return tem;
}
ds18b20.h
/**********************************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
**********************************/
#ifndef __DS18B20_H__
#define __DS18B20_H__
/**********************************
包含头文件
**********************************/
#include "main.h"
/**********************************
PIN口定义
**********************************/
#define DQ_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define DQ_Pin GPIO_PIN_15
#define DQ_GPIO_Port GPIOA
/**********************************
函数声明
**********************************/
void Ds18b20_GPIO_Init(void); //DS18B20初始化函数
unsigned int Ds18b20_Read_Temp(void); //读取温度值函数
//使用调用
#endif