做網(wǎng)站基本費(fèi)用大概需要多少sem專員
文章目錄
- 引言
- 電路圖
- 引腳講解
- 初始化時(shí)序
- 寫時(shí)序
- 讀時(shí)序
- 溫度變換
- 溫度讀取
- 完整代碼
引言
DS18B20是一款單總線接口的數(shù)字溫度傳感器,僅需一個(gè)IO口即可實(shí)現(xiàn)數(shù)據(jù)通信。這里只對如何簡單操作開發(fā)板的DS1802進(jìn)行講解,關(guān)于DS18B20溫度傳感器的詳細(xì)操作原理,可參考此博客:DS18B20數(shù)字溫度傳感器操作解析。
電路圖
下圖顯示了DS18B20的電路連接。數(shù)據(jù)總線通過J14排針引出,并連接到所選的IO口。數(shù)據(jù)總線上需要一個(gè)上拉電阻以確保穩(wěn)定的通信。
引腳講解
DS18B20傳感器通常采用TO-92封裝或PDIP封裝,具有以下三個(gè)主要引腳:
- VDD - 電源正極,為傳感器提供工作電壓。
- GND - 電源負(fù)極,接地。
- DQ - 數(shù)據(jù)引腳,用于與微控制器或計(jì)算機(jī)進(jìn)行數(shù)據(jù)通信。
引腳詳解
- VDD: 連接到傳感器的工作電壓,通常為3.3V或5V。確保不要超過傳感器的最大工作電壓,以避免損壞。
- GND: 連接到電路的地線,確保傳感器的穩(wěn)定工作。
- DQ: 是一個(gè)開漏輸出引腳,需要通過上拉電阻連接到VDD。這個(gè)引腳負(fù)責(zé)與主控制器進(jìn)行通信,支持1-Wire通信協(xié)議。
初始化時(shí)序
初始化過程從主機(jī)發(fā)送復(fù)位脈沖開始。主機(jī)將總線拉低至少480微秒(us),通常是500us,以確保所有從設(shè)備都能檢測到復(fù)位信號(hào)。復(fù)位脈沖后,總線需保持高電平15-60微秒,等待從設(shè)備響應(yīng)。
從設(shè)備通過發(fā)送存在脈沖來響應(yīng),表示它們已經(jīng)檢測到復(fù)位信號(hào),并將總線拉低60-240微秒。表明它已檢測到復(fù)位信號(hào)。之后將電平拉高。
sbit DS18B20_DQ = P3^7;unsigned char DS18B20_Init()
{unsigned char i;unsigned char ackBit;DS18B20_DQ = 1;DS18B20_DQ = 0;i = 247;while (--i); //延時(shí)500usDS18B20_DQ = 1;i = 32;while (--i);ackBit = DS18B20_DQ;i = 247;while (--i); //延時(shí)500usreturn ackBit;
}
寫時(shí)序
寫時(shí)序包括主機(jī)發(fā)送數(shù)據(jù)位“0”或“1”到從設(shè)備。每個(gè)位的寫入時(shí)序稍有不同。每次寫入一個(gè)數(shù)據(jù)位都需要初始化一個(gè)寫周期。主機(jī)將總線拉低至少1微秒(通常是1-15微秒),然后釋放總線,這是初始化寫周期。
寫0時(shí)序:
- 主機(jī)將總線拉低至少60微秒(通常是60-120微秒),然后釋放總線。
寫1時(shí)序:
- 主機(jī)將總線拉低至少1微秒(通常是1-15微秒),然后在剩余時(shí)間內(nèi)保持高電平(釋放總線)。
寫入一個(gè)字節(jié)(8位)需要重復(fù)上述寫0和寫1時(shí)序八次。寫入順序?yàn)榈臀辉谇?#xff08;LSB first)。
- 開始寫入字節(jié):初始化第一個(gè)寫周期。
- 寫入每個(gè)位:根據(jù)數(shù)據(jù)位的值,執(zhí)行寫0或?qū)?時(shí)序。
- 結(jié)束寫入字節(jié):完成8個(gè)位的寫入后,字節(jié)寫入結(jié)束。
假設(shè)我們要寫入字節(jié)0x5A(01011010)。
- 寫入0位:主機(jī)將總線拉低至少60微秒,釋放總線。
- 寫入1位:主機(jī)將總線拉低至少1微秒,釋放總線。
- 寫入0位:重復(fù)寫0時(shí)序。
- 寫入1位:重復(fù)寫1時(shí)序。
- 寫入1位:重復(fù)寫1時(shí)序。
- 寫入0位:重復(fù)寫0時(shí)序。
- 寫入1位:重復(fù)寫1時(shí)序。
- 寫入0位:重復(fù)寫0時(shí)序。
//發(fā)送一位
void ds18b20_write_bit(unsigned char bits)
{ unsigned char i;DS18B20_DQ = 0;i = 4;while (--i); //延時(shí)10usDS18B20_DQ = bits;i = 24;while (--i); //延時(shí)50usDS18B20_DQ = 1;
}//發(fā)送字節(jié)
void ds18b20_write_byte(unsigned char byte)
{unsigned char i;for(i = 0;i<8;i++){ds18b20_write_bit(byte & 0x01<<i);//先發(fā)送低位}
}
讀時(shí)序
每次讀取一個(gè)數(shù)據(jù)位都需要初始化一個(gè)讀周期。初始化讀周期期間需要主機(jī)將總線拉低至少1微秒(通常是1-15微秒),然后釋放總線。之后讀取數(shù)據(jù)位,主機(jī)在讀周期內(nèi)讀取從設(shè)備發(fā)送的數(shù)據(jù)位。需要主機(jī)將總線拉低至少1微秒(通常是1-15微秒)。然后釋放總線,主機(jī)釋放總線,并在15微秒內(nèi)讀取總線狀態(tài)。讀取數(shù)據(jù)位期間如果總線保持低電平,讀取到的數(shù)據(jù)位為0;如果總線拉高,讀取到的數(shù)據(jù)位為1。要讀取一個(gè)字節(jié)(8位),需要重復(fù)上述讀取數(shù)據(jù)位的過程八次,按低位在前(LSB first)的順序讀取。
假設(shè)我們要讀取一個(gè)字節(jié)的數(shù)據(jù),具體步驟如下:
- 初始化讀周期:主機(jī)將總線拉低至少1微秒,然后釋放總線。
- 讀取每個(gè)位:在讀周期內(nèi),主機(jī)讀取從設(shè)備發(fā)送的每個(gè)位數(shù)據(jù)。
- 完成字節(jié)讀取:重復(fù)上述步驟八次,讀取一個(gè)完整的字節(jié)。
//接收一位
unsigned char ds18b20_read_bit()
{ unsigned char i;unsigned char bits;DS18B20_DQ = 0;i = 2;while (--i); //延時(shí)5usDS18B20_DQ = 1;i = 2;while (--i); //延時(shí)5usbits = DS18B20_DQ;i = 24;while (--i); //延時(shí)50usreturn bits;
}unsigned char ds18b20_read_byte()
{unsigned char i;unsigned char byte = 0x00;for(i = 0;i<8;i++){if(ds18b20_read_bit()){byte |= 0x01<<i; }}return byte;
}
溫度變換
DS18B20溫度傳感器的溫度轉(zhuǎn)換功能允許用戶讀取精確的溫度數(shù)據(jù)。為了實(shí)現(xiàn)溫度轉(zhuǎn)換,必須遵循特定的時(shí)序和命令流程。
溫度轉(zhuǎn)換流程包括以下幾個(gè)主要步驟:
- 發(fā)送初始化命令:主機(jī)需要發(fā)送初始化命令來復(fù)位總線并檢測從設(shè)備的存在。
- 跳過ROM命令:向總線上的所有設(shè)備廣播命令。所有設(shè)備都會(huì)響應(yīng)接下來的命令。
- 發(fā)送啟動(dòng)溫度轉(zhuǎn)換命令:0x44用于啟動(dòng)溫度轉(zhuǎn)換(Convert T)
//轉(zhuǎn)換溫度
void ds18b20_ConvertT()
{DS18B20_Init();ds18b20_write_byte(0xCC);ds18b20_write_byte(0x44);
}
溫度讀取
讀取DS18B20溫度傳感器的數(shù)據(jù)是一個(gè)包括命令發(fā)送和數(shù)據(jù)處理的過程。
溫度讀取過程包括以下幾個(gè)主要步驟:
- 發(fā)送初始化命令:主機(jī)需要發(fā)送初始化命令來復(fù)位總線并檢測從設(shè)備的存在。
- 跳過ROM命令:向總線上的所有設(shè)備廣播命令。所有設(shè)備都會(huì)響應(yīng)接下來的命令。
- 發(fā)送讀暫存器命令:用于從DS18B20傳感器的暫存器中讀取溫度數(shù)據(jù)、報(bào)警閾值和配置寄存器信息。
先讀取低位,后讀取高位,溫度數(shù)據(jù)是16位帶符號(hào)的二進(jìn)制數(shù),最低位代表 2 ? 4 2^{-4} 2?4攝氏度(即0.0625攝氏度)
//讀取溫度
float ds18b20_ReadT()
{unsigned char byteL;unsigned char byteH;int temp;float T;DS18B20_Init();ds18b20_write_byte(0xCC);ds18b20_write_byte(0xBE);byteL = ds18b20_read_byte();//低字節(jié)byteH = ds18b20_read_byte();//高字節(jié)temp = (byteH << 8) | byteL;T = temp / 16.0;return T;
}
完整代碼
LCD1602液晶顯示屏實(shí)時(shí)獲取溫度變化
#include <REGX52.H>
#include <LCD1602.H>
#include "stdio.h"
sbit DS18B20_DQ = P3^7;unsigned char DS18B20_Init()
{unsigned char i;unsigned char ackBit;DS18B20_DQ = 1;DS18B20_DQ = 0;i = 247;while (--i); //延時(shí)500usDS18B20_DQ = 1;i = 32;while (--i);ackBit = DS18B20_DQ;i = 247;while (--i); //延時(shí)500usreturn ackBit;
}//發(fā)送一位
void ds18b20_write_bit(unsigned char bits)
{ unsigned char i;DS18B20_DQ = 0;i = 4;while (--i); //延時(shí)10usDS18B20_DQ = bits;i = 24;while (--i); //延時(shí)50usDS18B20_DQ = 1;
}//接收一位
unsigned char ds18b20_read_bit()
{ unsigned char i;unsigned char bits;DS18B20_DQ = 0;i = 2;while (--i); //延時(shí)5usDS18B20_DQ = 1;i = 2;while (--i); //延時(shí)5usbits = DS18B20_DQ;i = 24;while (--i); //延時(shí)50usreturn bits;
}//發(fā)送字節(jié)
void ds18b20_write_byte(unsigned char byte)
{unsigned char i;for(i = 0;i<8;i++){ds18b20_write_bit(byte & 0x01<<i);//先發(fā)送低位}
}unsigned char ds18b20_read_byte()
{unsigned char i;unsigned char byte = 0x00;for(i = 0;i<8;i++){if(ds18b20_read_bit()){byte |= 0x01<<i; }}return byte;
}//轉(zhuǎn)換溫度
void ds18b20_ConvertT()
{DS18B20_Init();ds18b20_write_byte(0xCC);ds18b20_write_byte(0x44);
}//讀取溫度
float ds18b20_ReadT()
{unsigned char byteL;unsigned char byteH;int temp;float T;DS18B20_Init();ds18b20_write_byte(0xCC);ds18b20_write_byte(0xBE);byteL = ds18b20_read_byte();//低字節(jié)byteH = ds18b20_read_byte();//高字節(jié)temp = (byteH << 8) | byteL;T = temp / 16.0;return T;
}unsigned char ack = 1;float g_T;void main()
{char temp_buff[50];LCD_Init();LCD_ShowString(1,1,"helloworld");ack = DS18B20_Init();LCD_ShowNum(2,1,ack,3);while(1){ds18b20_ConvertT();g_T = ds18b20_ReadT();if(g_T<0){//負(fù)數(shù)LCD_ShowChar(2,1,'-');g_T = -g_T;}else{LCD_ShowChar(2,1,'+');}// 使用 sprintf 將浮點(diǎn)數(shù)轉(zhuǎn)換為字符串sprintf(temp_buff, "%.3f", g_T);LCD_ShowString(2,2,temp_buff);}
}