|
DS18B20 是由 DALLAS 半導(dǎo)體公司推出的一種的“一線總線”接口的溫度傳感器。與傳
的熱敏電阻等測溫元件相比,它是一種新型的體積小、適用電壓寬、與微處理器接口簡單的
字化溫度傳感器。一線總線結(jié)構(gòu)具有簡潔且經(jīng)濟的特點,可使用戶輕松地組建傳感器網(wǎng)絡(luò),
而為測量系統(tǒng)的構(gòu)建引入全新概念,測量溫度范圍為-55~+125℃ ,精度為±0. 5℃。現(xiàn)場溫
直接以“一線總線”的數(shù)字方式傳輸,大大提高了系統(tǒng)的抗干擾性。它能直接讀出被測溫度,
且可根據(jù)實際要求通過簡單的編程實現(xiàn) 9~l2 位的數(shù)字值讀數(shù)方式。它工作在 3—5. 5 V 的電
范圍,采用多種封裝形式,從而使系統(tǒng)設(shè)計靈活、方便,設(shè)定分辨率及用戶設(shè)定的報警溫度
儲在 EEPROM 中,掉電后依然保存。其內(nèi)部結(jié)構(gòu)如圖 35.1.1 所示:
圖 35.1.1 DS18B20 內(nèi)部結(jié)構(gòu)圖
ROM 中的 64 位序列號是出廠前被光記好的,它可以看作是該 DS18B20 的地址序列碼,每
18B20 的 64 位序列號均不相同。 64 位 ROM 的排列是:前 8 位是產(chǎn)品家族碼,接著 48 位是
18B20 的序列號,最后 8 位是前面 56 位的循環(huán)冗余校驗碼(CRC=X8+X5 +X4 +1)。 ROM 作
是使每一個 DS18B20 都各不相同,這樣就可實現(xiàn)一根總線上掛接多個。
所有的單總線器件要求采用嚴(yán)格的信號時序,以保證數(shù)據(jù)的完整性。 DS18B20 共有 6 種信
類型:復(fù)位脈沖、應(yīng)答脈沖、寫 0、寫 1、讀 0 和讀 1。所有這些信號,除了應(yīng)答脈沖以外,
由主機發(fā)出同步信號。并且發(fā)送所有的命令和數(shù)據(jù)都是字節(jié)的低位在前。這里我們簡單介紹
幾個信號的時序:
1)復(fù)位脈沖和應(yīng)答脈沖
單總線上的所有通信都是以初始化序列開始。主機輸出低電平,保持低電平時間至少 480
,以產(chǎn)生復(fù)位脈沖。接著主機釋放總線, 4.7K 的上拉電阻將單總線拉高,延時 15~60 us,
進入接收模式(Rx)。接著 DS18B20 拉低總線 60~240 us,以產(chǎn)生低電平應(yīng)答脈沖,
若為低電平,再延時 480 us。
2)寫時序
寫時序包括寫 0 時序和寫 1 時序。所有寫時序至少需要 60us,且在 2 次獨立的寫時序之間
少需要 1us 的恢復(fù)時間,兩種寫時序均起始于主機拉低總線。寫 1 時序:主機輸出低電平,
時 2us,然后釋放總線,延時 60us。寫 0 時序:主機輸出低電平,延時 60us,然后釋放總線,
時 2us。
3)讀時序
單總線器件僅在主機發(fā)出讀時序時,才向主機傳輸數(shù)據(jù),所以,在主機發(fā)出讀數(shù)據(jù)命令后,
須馬上產(chǎn)生讀時序,以便從機能夠傳輸數(shù)據(jù)。所有讀時序至少需要 60us,且在 2 次獨立的讀
時序之間至少需要 1us 的恢復(fù)時間。每個讀時序都由主機發(fā)起,至少拉低總線 1us。主機在讀
時序期間必須釋放總線,并且在時序起始后的 15us 之內(nèi)采樣總線狀態(tài)。典型的讀時序過程為:
主機輸出低電平延時 2us,然后主機轉(zhuǎn)入輸入模式延時 12us,然后讀取單總線當(dāng)前的電平,然
后延時 50us。
在了解了單總線時序之后,我們來看看 DS18B20 的典型溫度讀取過程, DS18B20 的典型
溫度讀取過程為:復(fù)位發(fā) SKIP ROM 命令(0XCC) 發(fā)開始轉(zhuǎn)換命令(0X44) 延時復(fù)
位發(fā)送 SKIP ROM 命令(0XCC) 發(fā)讀存儲器命令(0XBE) 連續(xù)讀出兩個字節(jié)數(shù)據(jù)(即
溫度)結(jié)束。
DS18B20 的介紹就到這里,更詳細(xì)的介紹,請大家參考 DS18B20 的技術(shù)手冊。
35.2 硬件設(shè)計
由于開發(fā)板上標(biāo)準(zhǔn)配置是沒有 DS18B20 這個傳感器的,只有接口,所以要做本章的實驗,
大家必須找一個 DS18B20 插在預(yù)留的 18B20 接口上。
本章實驗功能簡介:開機的時候先檢測是否有 DS18B20 存在,如果沒有,則提示錯誤。
只有在檢測到 DS18B20 之后才開始讀取溫度并顯示在 LCD 上,如果發(fā)現(xiàn)了 DS18B20,則程
序每隔 100ms 左右讀取一次數(shù)據(jù),并把溫度顯示在 LCD 上。同樣我們也是用 DS0 來指示程序
正在運行。
所要用到的硬件資源如下:
1) 指示燈 DS0
2) TFTLCD 模塊
3) DS18B20 接口
4) DS18B20 溫度傳感器
我們使用的是 STM32的 PG11來連接 U13的 DQ引腳,圖中 U13為 DHT11
(數(shù)字溫濕度傳感器)和 DS18B20 共用的一個接口, DHT11 我們將在下一章介紹。
DS18B20 只用到 U6 的 3 個引腳(U6 的 1、 2 和 3 腳),將 DS18B20 傳感器插入到這個上
面就可以通過 STM32 來讀取 DS18B20 的溫度了。
軟件設(shè)計
打開我們的 DS18B20 數(shù)字溫度傳感器實驗工程可以看到我們添加了 ds18b20.c 文件以及其
頭文件 ds18b20.h 文件,所有 ds18b20 驅(qū)動代碼和相關(guān)定義都分布在這兩個文件中。
打開 ds18b20.c, 該文件代碼如下:
#include "ds18b20.h"
#include "delay.h"
//復(fù)位 DS18B20
void DS18B20_Rst(void)
{
DS18B20_IO_OUT(); //SET PA0 OUTPUT
DS18B20_DQ_OUT=0; //拉低 DQ
delay_us(750); //拉低 750us
DS18B20_DQ_OUT=1; //DQ=1
delay_us(15); //15US
}
//等待 DS18B20 的回應(yīng)
//返回 1:未檢測到 DS18B20 的存在
//返回 0:存在
u8 DS18B20_Check(void)
{
u8 retry=0;
DS18B20_IO_IN();//SET PA0 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) // read one bit
{
u8 data;
DS18B20_IO_OUT();//SET PA0 OUTPUT
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_IN();//SET PA0 INPUT
delay_us(12);
if(DS18B20_DQ_IN)data=1;
else data=0;
delay_us(50);
return data;
}
//從 DS18B20 讀取一個字節(jié)
//返回值:讀到的數(shù)據(jù)
u8 DS18B20_Read_Byte(void) // read one byte
{
u8 i,j,dat;
dat=0;
for (i=1;i<=8;i++)
{
j=DS18B20_Read_Bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
//寫一個字節(jié)到 DS18B20
//dat:要寫入的字節(jié)
void DS18B20_Write_Byte(u8 dat)
{
u8 j;
u8 testb;
DS18B20_IO_OUT();//SET PA0 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);
}
}
}
//開始溫度轉(zhuǎn)換
void DS18B20_Start(void)// ds1820 start convert
{
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); //使能 PG 口時鐘
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
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; //溫度為負(fù)
}else temp=1; //溫度為正
tem=TH; //獲得高八位
tem<<=8;
tem+=TL; //獲得底八位
tem=(float)tem*0.625; //轉(zhuǎn)換
if(temp)return tem; //返回溫度值
else return -tem;
}
該部分代碼就是根據(jù)我們前面介紹的單總線操作時序來讀取 DS18B20 的溫度值的,DS18B20
的溫度通過 DS18B20_Get_Temp 函數(shù)讀取,該函數(shù)的返回值為帶符號的短整形數(shù)據(jù),返回值的
范圍為-550~1250,其實就是溫度值擴大了 10 倍。
然后我們打開 ds18b20.h,該文件下面主要是一些 IO 口位帶操作定義以及函數(shù)申明,沒有
什么特別需要講解的地方。最后打開 main.c,該文件代碼如下:
int main(void)
{
u8 t=0;
short temperature;
delay_init(); //延時函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷優(yōu)先級分組為組 2
uart_init(115200); //串口初始化為 115200
LED_Init(); //初始化與 LED 連接的硬件接口
LCD_Init(); //初始化 LCD
POINT_COLOR=RED; //設(shè)置字體為紅色
LCD_ShowString(30,50,200,16,16,"WarShip STM32");
LCD_ShowString(30,70,200,16,16,"DS18B20 TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2015/1/16");
while(DS18B20_Init()) //DS18B20 初始化
{
LCD_ShowString(30,130,200,16,16,"DS18B20 Error");
delay_ms(200);
LCD_Fill(30,130,239,130+16,WHITE);
delay_ms(200);
}
LCD_ShowString(30,130,200,16,16,"DS18B20 OK");
POINT_COLOR=BLUE;//設(shè)置字體為藍色
LCD_ShowString(30,150,200,16,16,"Temp: . C");
while(1)
{
if(t%10==0) //每 100ms 讀取一次
{
temperature=DS18B20_Get_Temp();
if(temperature<0)
{
LCD_ShowChar(30+40,150,'-',16,0); //顯示負(fù)號
temperature=-temperature; //轉(zhuǎn)為正數(shù)
}else LCD_ShowChar(30+40,150,' ',16,0); //去掉負(fù)號
LCD_ShowNum(30+40+8,150,temperature/10,2,16); //顯示正數(shù)部分
LCD_ShowNum(30+40+32,150,temperature%10,1,16); //顯示小數(shù)部分
}
delay_ms(10);
t++;
if(t==20)
{
t=0;
LED0=!LED0;
}
}
}
主函數(shù)代碼很簡單,一系列初始化之后,就是每 100ms 讀取一次 18B20 的值,然后轉(zhuǎn)化為
溫度后顯示在 LCD 上
全部資料51hei下載地址:
18B20數(shù)字溫度傳感器源代碼.7z
(221.62 KB, 下載次數(shù): 8)
2019-10-12 22:09 上傳
點擊文件名下載附件
軟件代碼 下載積分: 黑幣 -5
|
|