一、項目介紹
當前文章介紹基于51單片機和SHT30傳感器設計的環境溫度與濕度檢測設備。設備采用IIC模擬時序通信協議,能夠實時監測環境的溫度和濕度,并將數據通過LCD顯示屏顯示出來;可以廣泛應用于室內環境監測、氣象觀測、農業溫室監測等領域。
在本項目中,使用了51單片機作為主控芯片,SHT30傳感器作為溫濕度傳感器,LCD顯示屏作為數據顯示模塊。通過51單片機的GPIO口模擬IIC通信協議,實現了與SHT30傳感器的數據通信。
二、硬件設計
2.1 硬件構成
本次設計所需的硬件主要包括以下部分:
2.2 硬件接口及信號
本次設計使用51單片機通過IIC總線與SHT30傳感器進行通信,同時使用串口與上位機進行數據傳輸,并使用液晶顯示屏顯示當前溫濕度值。
具體接口和信號定義如下:
(1) 51單片機與SHT30傳感器之間的IIC接口:
端口 | 功能 | 說明 |
---|---|---|
P2.0 | SDA | 數據線 |
P2.1 | SCL | 時鐘線 |
P2.2 | RESET | 復位線 |
(2) 51單片機與串口通信模塊之間的接口:
端口 | 功能 | 說明 |
---|---|---|
P3.0 | TXD | 發送線 |
P3.1 | RXD | 接收線 |
P3.2 | GND | 地線 |
(3) 51單片機與液晶屏之間的接口:
端口 | 功能 | 說明 |
---|---|---|
P1.0-P1.7 | DB0-DB7 | 數據線 |
P0.0 | RS | 指令/數據選擇線 |
P0.1 | RW | 讀/寫選擇線 |
P0.2 | E | 使能線 |
P0.3 | CS | 片選線 |
VCC | 電源正極 | 5V |
GND | 電源地 | 地 |
三、軟件設計
3.1 SHT30傳感器代碼
下面代碼讀取SHT30傳感器的值并通過串口打印。
#include < REG52.h >
#include < stdio.h >
?
#define uchar unsigned char
#define uint unsigned int
?
sbit SDA=P2^0;
sbit SCL=P2^1;
?
void delay(int n)
{
int i;
while(n--)
{
for(i=0; i< 120; i++);
}
}
?
void start()
{
SDA = 1;
_nop_();
SCL = 1;
_nop_();
SDA = 0;
_nop_();
SCL = 0;
_nop_();
}
?
void stop()
{
SDA = 0;
_nop_();
SCL = 1;
_nop_();
SDA = 1;
_nop_();
}
?
void ack()
{
SDA = 0;
_nop_();
SCL = 1;
_nop_();
SCL = 0;
_nop_();
SDA = 1;
_nop_();
}
?
void nack()
{
SDA = 1;
_nop_();
SCL = 1;
_nop_();
SCL = 0;
_nop_();
}
?
void write_byte(uchar dat)
{
uchar i;
for(i=0; i< 8; i++)
{
SDA = dat & 0x80;
_nop_();
SCL = 1;
_nop_();
SCL = 0;
_nop_();
dat < <= 1;
}
ack();
}
?
uchar read_byte()
{
uchar i, dat;
for(i=0; i< 8; i++)
{
dat < <= 1;
SCL = 1;
_nop_();
dat |= SDA;
SCL = 0;
_nop_();
}
return dat;
}
?
void init_sht30()
{
start();
write_byte(0x80);
if(read_byte() != 0x5A)
{
stop();
return;
}
write_byte(0xBE);
if(read_byte() != 0x08 || read_byte() != 0x00)
{
stop();
return;
}
stop();
}
?
float measure_temp(void)
{
uchar temp_h, temp_l, crc;
float temp;
?
start();
write_byte(0x80); // 主機發送寫地址
write_byte(0x2C); // 選擇開始溫度測量命令
write_byte(0x06);
stop();
?
delay(15); // 延時等待溫度測量完成
?
start();
write_byte(0x81); // 主機發送讀地址
temp_h=read_byte();
ack();
temp_l=read_byte();
ack();
crc=read_byte