【1】DS18B20介紹
DS18B20是一種數(shù)字溫度傳感器,由Maxim Integrated公司生產(chǎn)。它采用單總線接口,能夠在廣泛的溫度范圍內(nèi)測(cè)量溫度,并通過(guò)數(shù)字方式輸出溫度值,具有較高的精度和穩(wěn)定性。
以下是DS18B20溫度傳感器的主要特點(diǎn)和操作時(shí)序:
(1)特點(diǎn):
- 單總線接口:DS18B20使用單一的數(shù)據(jù)線進(jìn)行通信,簡(jiǎn)化了連接和控制。
- 高精度測(cè)量:具有12位的溫度分辨率,可測(cè)量范圍為-55°C至+125°C。
- 數(shù)字輸出:溫度值以二進(jìn)制形式傳輸,便于處理和解析。
- 內(nèi)部存儲(chǔ):傳感器可內(nèi)部存儲(chǔ)溫度數(shù)據(jù)和配置信息。
- 低功耗:在非活動(dòng)狀態(tài)下,傳感器可以進(jìn)入睡眠模式以降低功耗消耗。
(2)操作時(shí)序: DS18B20的操作時(shí)序包括復(fù)位、寫(xiě)入指令、讀取溫度等過(guò)程。下面是DS18B20的基本操作時(shí)序:
a. 復(fù)位:
- 主機(jī)拉低數(shù)據(jù)線,持續(xù)至少480μs作為復(fù)位信號(hào)。
- 主機(jī)釋放數(shù)據(jù)線,等待15μs以上。
b. 發(fā)送指令:
- 主機(jī)發(fā)出寫(xiě)入指令(如跳過(guò)ROM指令或匹配ROM指令)。
- 指令由主機(jī)通過(guò)數(shù)據(jù)線逐位發(fā)送,每位的有效時(shí)間為60μs。
c. 讀取溫度:
- 主機(jī)發(fā)出讀取溫度指令。
- 傳感器將溫度數(shù)據(jù)以序列的形式發(fā)送給主機(jī),每位的有效時(shí)間為60μs。
- 主機(jī)在接收到所有數(shù)據(jù)后,需提供適當(dāng)?shù)难舆t時(shí)間進(jìn)行解析和處理。
【2】硬件連線說(shuō)明
STM32F407開(kāi)發(fā)板DS18B20應(yīng)用案例
開(kāi)發(fā)板硬件連接:
【3】源代碼
在工程中添加ds18b20.c和ds18b20.h文件。
DS18B20代碼如下:
#include "ds18b20.h"
/*
函數(shù)功能:DS18b20IO口初始化
硬件連接:PG9
復(fù)用表示自動(dòng)輸出數(shù)據(jù)
通用表示手動(dòng)輸出數(shù)據(jù)
*/
void DS18B20_Init(void)
{
/*1. 開(kāi)時(shí)鐘*/
RCC->AHB1ENR|=1<<6;//使能PORTG時(shí)鐘
/*2. 初始化IO模式*/
DS18B20_OUTPUT();
}
/*
函數(shù)功能:等待DS18B20的回應(yīng)
返回1:未檢測(cè)到DS18B20的存在
返回0:存在
*/
u8 DS18B20_Check(void)
{
u8 retry=0;
DS18B20_INPUT() //設(shè)置DS18B20輸入模式
while(DS18B20_IN&&retry<200)
{
retry++;
DelayUs(1);
};
if(retry>=200)return 1;
else retry=0;
while(!DS18B20_IN&&retry<240)
{
retry++;
DelayUs(1);
};
if(retry>=240)return 1;
return 0;
}
/*
從DS18B20讀取一個(gè)字節(jié)
返回值:讀到的數(shù)據(jù)
*/
u8 DS18B20_ReadByte(void)
{
u8 i,data=0;
for(i=0;i<8;i++)
{
DS18B20_OUTPUT(); //初始化為輸出模式
DS18B20_OUT=0; //輸出0
DelayUs(2);
DS18B20_OUT=1; //上拉總線電平
DS18B20_INPUT() //初始化為輸入模式
DelayUs(12);
data>>=1;
if(DS18B20_IN)
{
data|=0x80;
}
DelayUs(50);
}
return data;
}
/*
寫(xiě)一個(gè)字節(jié)到DS18B20
dat:要寫(xiě)入的字節(jié)
*/
void DS18B20_WriteByte(u8 dat)
{
u8 i;
DS18B20_OUTPUT(); //初始化IO為輸出模式
for(i=0;i<8;i++)
{
if(dat&0x01) //先發(fā)低位
{
DS18B20_OUT=0;//輸出0
DelayUs(2);
DS18B20_OUT=1;//輸出1
DelayUs(60);
}
else
{
DS18B20_OUT=0;//輸出0
DelayUs(60);
DS18B20_OUT=1;//輸出1
DelayUs(2);
}
dat>>=1;
}
}
/*
從ds18b20得到溫度值
精度:0.1C
返回值:溫度值 (-550~1250)
*/
short DS18B20_Get_Temp(void)
{
u16 temp;
u8 TL,TH;
DS18B20_OUTPUT();
DS18B20_OUT=0; //輸出0 //拉低DQ
DelayUs(750); //拉低750us
DS18B20_OUT=1; //輸出1 //DQ=1
DelayUs(15); //15US
DS18B20_Check();
DS18B20_WriteByte(0xcc); //跳過(guò)芯片ID檢測(cè)
DS18B20_WriteByte(0x44); //轉(zhuǎn)換一次溫度
DS18B20_OUTPUT();
DS18B20_OUT=0; //輸出0 //拉低DQ
DelayUs(750); //拉低750us
DS18B20_OUT=1; //輸出1 //DQ=1
DelayUs(15); //15US
DS18B20_Check();
DS18B20_WriteByte(0xcc);// 跳過(guò)芯片ID檢測(cè)
DS18B20_WriteByte(0xbe);// 讀取轉(zhuǎn)換成功的溫度數(shù)據(jù)
TL=DS18B20_ReadByte(); // LSB
TH=DS18B20_ReadByte(); // MSB
temp=((u16)TH<<8)|TL;
return temp;
}
Ds18b20.h代碼示例
#ifndef _DS18B20_H
#define _DS18B20_H
#include "stm32f4xx.h"
#include "sys.h"
#include "delay.h"
void DS18B20_Init(void);
short DS18B20_Get_Temp(void);
#define DS18B20_IN PGin(9)
#define DS18B20_OUT PGout(9)
#define DS18B20_INPUT()
{
GPIOG->MODER&=~(0x3<<9*2);
GPIOG->MODER|=0x0<<9*2;
GPIOG->PUPDR&=~(0x3<<9*2);
GPIOG->PUPDR|=0x1<<9*2;
}
#define DS18B20_OUTPUT()
{
GPIOG->MODER&=~(0x3<<9*2);
GPIOG->MODER|=0x1<<9*2;
GPIOG->OTYPER&=~(0x1<<9);
GPIOG->OSPEEDR&=~(0x3<<9*2);
GPIOG->OSPEEDR|=0x2<<9*2;
GPIOG->ODR|=1<<9;
}
#endif
Main.c文件示例
#include "stm32f4xx.h" // Device header
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "sys.h"
#include "exti.h"
#include "timer.h"
#include "pwm.h"
#include "ds18b20.h"
int main(void)
{
short temp;
unsigned short intT,decT; //溫度值的整數(shù)和小數(shù)部分
LED_Init();
KEY_Init();
USART1_Init(84,115200);
KEY_EXTI_Init();
DS18B20_Init();
while(1)
{
/*讀取溫度信息*/
temp=DS18B20_Get_Temp();
intT = temp >> 4; //分離出溫度值整數(shù)部分
decT = temp & 0xF; //分離出溫度值小數(shù)部分
printf("DS18B20: %d.%d *Crn",(int)intT,(int)decT);
DelayMs(1000);
}
}