DS18B20需要在QD引脚并联一个4.7KΩ左右的电阻作为上拉电阻,GND引脚接地,DQ接所用引脚,上拉电阻接3.3V,VDD引脚接3.3V。
DS18B20.h
#include"includes.h"
/*该头文件为自定义头文件,根据自己需要添加相应文件,如<stm32f10x.h>,<stm32f10x_Conf.h>,<stm32f10x_it.h>,<DS18B20.h>等*/
#ifndef __DS18B20_H__
#define __DS18B20_H__
//DS18B20 CMD 命令集
#define SkipROM 0xCC //跳过ROM
#define SearchROM 0xF0 //搜索ROM
#define ReadROM 0x33 //读ROM
#define MatchROM 0x55 //匹配ROM
#define AlarmROM 0xEC //告警ROM
#define StartConvert 0x44 //开始温度转换
#define ReadScratchpad 0xBE //读暂存器的9个字节
#define WriteScratchpad 0x4E //写暂存器的温度告警TH和TL
#define CopyScratchpad 0x48 //将暂存器的温度告警复制到EEPROM,备份设置
#define RecallEEPROM 0xB8 //将EEPROM的温度告警复制到暂存器,恢复设置
#define ReadPower 0xB4 //读供电方式:0为寄生电源,1为外部电源
#define SetDQ() GPIO_SetBits(GPIOC,GPIO_Pin_6)
#define ResetDQ() GPIO_ResetBits(GPIOC,GPIO_Pin_6)
#define GetQD() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)
float DS18B20_Read(void);//读取数据
uint8_t ResetDS18B20(void);//复位DS18B20
#endif
DS18B20.c
#include"includes.h"
uint8_t ResetDS18B20(void)
{
uint8_t Data = 1;
SetDQ();
Delay_US(50);
ResetDQ();
Delay_US(500); /*该时间的时间范围为480——960us*/
SetDQ();
Delay_US(90);
Data = GetDQ();
Delay_US(510);
SetDQ();
return Data;
}
/*写数据*/
void DS18B20WriteByte(uint8_t Dat)
{
uint8_t i = 0;
for(i=8;i>0;i--)
{
ResetDQ(); /*在15us内送数到数据线上,DS18B20在15-60us读数*/
Delay_Us(10);
if(Dat & 0x01)
{
SetDQ();
}
else
{
ResetDQ();
}
}
Delay_Us(65);
SetDQ();
Delay_Us(5); //连续两位间应大于1us
Dat >>= 1;
}
/*读数据*/
uint8_t DS18B30ReadByte(void)
{
uint8_t i=0,data=0;
SetDQ();
Delay_Us(5);
for(i=8;i>0;i--)
{
ResetDQ();
Delay_Us(10); /*从读时序开始到采样信号线必须在15us内,且采样尽量安排在15us最后*/
SetDQ();
Delay_Us(10);
data>>=1;
if(GetDQ())
{
data|=0x80;
}
else
{
data&=0x7f
}
Delay_Us(45);
SetDQ();
}
return data;
}
/*启动转换*/
void DS18B20StartConvert(void)
{
ResetDS18B20();
DS18B20WriteByte(SkipROM);
DS18B20WriteBYte(StartConvert);
}
/*获取温度*/
float DS18B20_Read(void)
{
Static uint8_t DL = 0,DH = 0;
uint8_t TemperatureData = 0;
float Temperature = 0;
_set_PRIMASK(1); /*关闭总中断*/
DS18B20StartConvert();
ResetDS18B20();
DS18B20WriteByte(SkipROM);
DS18B20WriteByte(ReadScratchpad);
DL = DS18B30ReadByte();
DH = DS18B30ReadByte();
_set_PRIMASK(0); /*打开总中断*/
TemperatureData = DH;
TemperatureData <<=8;
TemperatureData |= DL;
if(TemperatureData & 0xF800)
{
TemperatureData =~TemperatureData+1;
Temperature =-TemperatureData*0.0625;
}
else
{
Temperature = TemperatureData*0.0625;/*分辨率为0.0625*/
}
return Temperature;
}
注意 DQ的管脚模式为 GPIO_mode_Out_OD;
int main(void)
{
/*
此处填写GPIO初始化,延迟函数初始化,串口初始化等
*/
while(1)
{
printf("%.2f",DS18B20_Read());
}
}