一、項目介紹
溫度檢測是工業自動化、生產線等眾多領域中常見的應用場景之一,能及時準確地監測溫度對于保障生產安全和提高生產效率有著非常重要的作用。而在現代的電子制造行業中,使用單片機和傳感器等電子元器件進行溫度檢測已經成為了一個比較成熟的技術方案。
本項目選擇STC89C52單片機和DS18B20數字溫度傳感器,通過讀取傳感器輸出的溫度值,經過計算和處理后,并將結果顯示在數碼管上,實現環境溫度的實時監測和顯示。其中,STC89C52單片機為主控芯片,負責接收和處理數字溫度傳感器的數據,并通過數碼管將溫度值進行顯示。
二、整體設計
【1】設計思路
使用 STC89C52 單片機和 DS18B20 數字溫度傳感器,通過 I/O 口進行連接,讀取傳感器輸出的溫度值。通過計算和處理后,將溫度值在數碼管上進行顯示。其中,STC89C52 單片機為主控芯片,負責接收和處理數字溫度傳感器的數據,并通過數碼管將溫度值進行顯示。
【2】硬件連接
硬件方面,需要使用 STC89C52 單片機和 DS18B20 數字溫度傳感器。其中,STC89C52 單片機通過 P1 口連接4位數碼管的動態掃描信號線,并與 DS18B20 傳感器的 DQ 線相連。DS18B20需要使用一個2.2K歐姆上拉電阻和一個10K歐姆下拉電阻。
【3】軟件設計
在軟件方面,主要進行以下操作:
(1)初始化函數
初始化串行總線,設置為推挽輸出,并將數碼管段選端口初始化為高電平輸出,數碼管位選端口初始化為低電平輸出。
(2)讀取溫度值函數
通過發送讀取命令,從 DS18B20 數字溫度傳感器中讀取溫度值。
(3)溫度值計算函數
根據 DS18B20 數字溫度傳感器的溫度值計算方法,將讀取到的數值進行轉換,得到實際溫度值。
(4)數碼管顯示函數
將溫度值分離出整數和小數部分,然后經過數碼管驅動程序,通過數碼管進行顯示。
三、具體代碼實現
【1】DS18B20溫度讀取
DS18B20 是一種數字溫度傳感器,采用單總線接口進行通訊。它可以在較長的距離內實現溫度值的準確測量,并且不需要調零或校準,被廣泛應用于各種計算機控制系統、電子設備和溫度控制應用中。其分辨率為 12 位,溫度范圍為 -55 度 Celsius 到 +125 度 Celsius。
下面代碼實現的功能是:讀取DS18B20溫度再通過串口打印出來。
#include < reg51.h >
?
#define uchar unsigned char
#define uint unsigned int
?
sbit DQ = P1^0; // DS18B20 數字溫度傳感器數據線連接到 P1.0 引腳
?
// DS18B20 數據傳輸函數
void DS18B20_WriteByte(uchar dat);
uchar DS18B20_ReadByte();
void DS18B20_Start();
void DS18B20_End();
void DS18B20_Delay(uint i);
?
// 初始化函數
void init();
?
// 串口初始化函數
void uart_init();
?
// 串口發送函數
void send_string(char *s);
?
void main()
{
uchar temp_h, temp_l;
uint temp;
?
init();
uart_init(); // 串口初始化
?
while(1)
{
DS18B20_Start(); // 啟動傳輸
DS18B20_WriteByte(0xCC); // 忽略 ROM 指令
DS18B20_WriteByte(0x44); // 發送溫度轉換指令
DS18B20_End(); // 結束傳輸
?
DS18B20_Start(); // 啟動傳輸
DS18B20_WriteByte(0xCC); // 忽略 ROM 指令
DS18B20_WriteByte(0xBE); // 發送讀取指令
?
// 讀取溫度值
temp_l = DS18B20_ReadByte(); // 讀取低位溫度值
temp_h = DS18B20_ReadByte(); // 讀取高位溫度值
?
// 計算溫度值
temp = (temp_h < < 8) + temp_l;
temp = (float)temp / 16;
send_string("The temperature is: ");
send_string(temp);
send_string("
");
?
DS18B20_End(); // 結束傳輸
}
}
?
// DS18B20 數據傳輸函數
void DS18B20_WriteByte(uchar dat)
{
uchar i;
?
for (i = 0; i < 8; i++)
{
DQ = 0; // 寫時序開始
DQ = dat & 0x01; // 寫數據
DS18B20_Delay(1); // 延時 1us
DQ = 1; // 寫時序結束
dat > >= 1;
}
}
?
uchar DS18B20_ReadByte()
{
uchar i, dat = 0;
?
for (i = 0; i < 8; i++)
{
DQ = 0; // 讀時序開始
DS18B20_Delay(1); // 延時 1us
dat > >= 1;
if(DQ)
dat |= 0x80;
DS18B20_Delay(5); // 延時 5us