當前文章介紹基于51單片機和SHT30傳感器設計的環(huán)境溫度與濕度檢測設備。設備采用IIC模擬時序通信協(xié)議,能夠?qū)崟r監(jiān)測環(huán)境的溫度和濕度,并將數(shù)據(jù)通過LCD顯示屏顯示出來;可以廣泛應用于室內(nèi)環(huán)境監(jiān)測、氣象觀測、農(nóng)業(yè)溫室監(jiān)測等領域。
(資料圖)
在本項目中,使用了51單片機作為主控芯片,SHT30傳感器作為溫濕度傳感器,LCD顯示屏作為數(shù)據(jù)顯示模塊。通過51單片機的GPIO口模擬IIC通信協(xié)議,實現(xiàn)了與SHT30傳感器的數(shù)據(jù)通信。
二、硬件設計2.1 硬件構成本次設計所需的硬件主要包括以下部分:
STC89C52單片機SHT30溫濕度傳感器串口通信模塊LCD1602顯示屏電源模塊杜邦線等連接線2.2 硬件接口及信號本次設計使用51單片機通過IIC總線與SHT30傳感器進行通信,同時使用串口與上位機進行數(shù)據(jù)傳輸,并使用液晶顯示屏顯示當前溫濕度值。
具體接口和信號定義如下:
(1) 51單片機與SHT30傳感器之間的IIC接口:
端口 | 功能 | 說明 |
---|---|---|
P2.0 | SDA | 數(shù)據(jù)線 |
P2.1 | SCL | 時鐘線 |
P2.2 | RESET | 復位線 |
(2) 51單片機與串口通信模塊之間的接口:
端口 | 功能 | 說明 |
---|---|---|
P3.0 | TXD | 發(fā)送線 |
P3.1 | RXD | 接收線 |
P3.2 | GND | 地線 |
(3) 51單片機與液晶屏之間的接口:
端口 | 功能 | 說明 |
---|---|---|
P1.0-P1.7 | DB0-DB7 | 數(shù)據(jù)線 |
P0.0 | RS | 指令/數(shù)據(jù)選擇線 |
P0.1 | RW | 讀/寫選擇線 |
P0.2 | E | 使能線 |
P0.3 | CS | 片選線 |
VCC | 電源正極 | 5V |
GND | 電源地 | 地 |
下面代碼讀取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); // 主機發(fā)送寫地址 write_byte(0x2C); // 選擇開始溫度測量命令 write_byte(0x06); stop(); ? delay(15); // 延時等待溫度測量完成 ? start(); write_byte(0x81); // 主機發(fā)送讀地址 temp_h=read_byte(); ack(); temp_l=read_byte(); ack(); crc=read_byte(); stop(); ? temp = ((temp_h< <8)+temp_l)*175.0/0xffff - 45.0; // 溫度值轉(zhuǎn)換公式 ? return temp; } ? float measure_humi(void) { uchar humi_h, humi_l, crc; float humi; ? start(); write_byte(0x80); // 主機發(fā)送寫地址 write_byte(0x2C); // 選擇開始濕度測量命令 write_byte(0x06); stop(); ? delay(15); // 延時等待濕度測量完成 ? start(); write_byte(0x81); // 主機發(fā)送讀地址 humi_h=read_byte(); ack(); humi_l=read_byte(); ack(); crc=read_byte(); stop(); ? humi = ((humi_h< <8)+humi_l)*100.0/0xffff; // 濕度值轉(zhuǎn)換公式 ? return humi; } ? void main() { float temp, humi; ? init_sht30(); // SHT30 初始化 ? TMOD=0x20; // 定時器0工作方式2,8位定時器,用于波特率設置 TH1=0xfd; // 波特率9600 TL1=0xfd; TR1=1; // 啟動定時器0 ? SCON=0x50; // 設置串口工作方式1,允許接收,允許接收中斷 ES=1; // 允許串口中斷 ? while(1) { temp = measure_temp(); humi = measure_humi(); printf("Temperature: %.1fC, Humidity: %.1f%\\n", temp, humi); delay(500); // 間隔時間500ms } } ? void ser() interrupt 4 using 2 { if(RI) // 接收到數(shù)據(jù) { RI=0; // 清除標志位 } if(TI) // 發(fā)送完畢 { TI=0; // 清除標志位 } }
在上面的代碼中,定義了兩個函數(shù) measure_temp
和 measure_humi
,分別用于測量溫度和濕度值,并返回結(jié)果。在主函數(shù)中,利用這兩個函數(shù)得到當前的溫濕度值,然后通過串口打印出來。
下面代碼是LCD1602驅(qū)動代碼,完成數(shù)字字符顯示。
#include < REG52.h > ? #define LCD1602_DB P0 sbit RS = P2^5; sbit RW = P2^6; sbit E = P2^7; ? void delay(int n) { int i; while(n--) { for(i=0; i< 120; i++); } } ? void main() { //LCD 初始化 delay(1000); LCD1602_DB = 0x38; E = 1; delay(5); E = 0; ? delay(500); LCD1602_DB = 0x08; E = 1; delay(5); E = 0; ? delay(500); LCD1602_DB = 0x01; E = 1; delay(5); E = 0; ? delay(500); LCD1602_DB = 0x06; E = 1; delay(5); E = 0; ? delay(500); LCD1602_DB = 0x0C; E = 1; delay(5); E = 0; ? while(1) { //向LCD中寫入數(shù)字12345 RS = 0; //選擇指令寄存器? LCD1602_DB = 0x80; //設置地址為第一行的第一個字符位置(0x80 + 0x00) ? E = 1; delay(5); E = 0; ? RS = 1; //選擇數(shù)據(jù)寄存器 ? LCD1602_DB = 0x31; //寫入數(shù)字1 E = 1; delay(5); E = 0; ? LCD1602_DB = 0x32; //寫入數(shù)字2 E = 1; delay(5); E = 0; ? LCD1602_DB = 0x33; //寫入數(shù)字3 E = 1; delay(5); E = 0; ? LCD1602_DB = 0x34; //寫入數(shù)字4 E = 1; delay(5); E = 0; ? LCD1602_DB = 0x35; //寫入數(shù)字5 E = 1; delay(5); E = 0; ? delay(500); //間隔時間為500ms } }
在上面的代碼中,定義了函數(shù) delay
用于延時等待,并且實現(xiàn)了LCD1602的初始化和寫入操作。在主函數(shù)中,執(zhí)行LCD1602的初始化操作,然后循環(huán)不斷向LCD中寫入數(shù)字12345,并且間隔時間為500ms。
#include< reg52.h > #include< intrins.h > ? #define uchar unsigned char #define uint unsigned int ? sbit SDA = P2^0; //定義SDA引腳 sbit SCL = P2^1; //定義SCL引腳 sbit CS = P0^3; //定義液晶屏片選引腳 sbit RW = P0^1; //定義液晶屏讀/寫引腳 sbit RS = P0^0; //定義液晶屏指令/數(shù)據(jù)引腳 sbit E = P0^2; //定義液晶屏使能引腳 ? void delay(int n) //延時函數(shù),n為延時時間 { int i; while(n--) { for(i=0; i< 120; i++); } } ? void start() //開始信號 { SDA = 1; //數(shù)據(jù)線高電平 _nop_(); SCL = 1; //時鐘線高電平 _nop_(); SDA = 0; //數(shù)據(jù)線低電平 _nop_(); SCL = 0; //時鐘線低電平 _nop_(); } ? void stop() //結(jié)束信號 { SDA = 0; //數(shù)據(jù)線低電平 _nop_(); SCL = 1; //時鐘線高電平 _nop_(); SDA = 1; //數(shù)據(jù)線高電平 _nop_(); } ? void ack() //應答信號 { SDA = 0; //數(shù)據(jù)線低電平 _nop_(); SCL = 1; //時鐘線高電平 _nop_(); SCL = 0; //時鐘線低電平 _nop_(); SDA = 1; //數(shù)據(jù)線高電平 _nop_(); } ? void nack() //非應答信號 { SDA = 1; //數(shù)據(jù)線高電平 _nop_(); SCL = 1; //時鐘線高電平 _nop_(); SCL = 0; //時鐘線低電平 _nop_(); } ? void write_byte(uchar dat) //寫一個字節(jié) { uchar i; for(i=0; i< 8; i++) { SDA = dat & 0x80; _nop_(); SCL = 1; _nop_(); SCL = 0; _nop_(); dat < <= 1; } ack(); } ? uchar read_byte() //讀一個字節(jié) { uchar i, dat; for(i=0; i< 8; i++) { dat < <= 1; SCL = 1; _nop_(); dat |= SDA; SCL = 0; _nop_(); } return dat; } ? void init_sht30() //SHT30初始化 { start(); write_byte(0x80); if(read_byte() != 0x5A) { stop(); return; } write_byte(0xBE); if(read_byte() != 0x08 || read_byte() != 0x00) { stop(); return; } stop(); } ? void measure() //測量溫濕度值 { float humi, temp; uint i; start(); write_byte(0x80); read_byte(); read_byte(); read_byte(); write_byte(0x2C); write_byte(0x06); for(i=0; i< 40000; i++); //等待測量結(jié)果 start(); write_byte(0x80); read_byte(); read_byte(); read_byte(); humi = read_byte() * 256; humi += read_byte(); temp = read_byte() * 256; temp += read_byte(); stop(); temp = -45 + (175*temp)/65535; //轉(zhuǎn)化溫度 humi = 100 * humi / 65535; //轉(zhuǎn)化濕度 //將溫濕度值通過串口發(fā)送 printf("Temperature: %.1fC\\n", temp); printf("Humidity: %.1f%%RH\\n", humi); } ? void init_lcd() //液晶屏初始化 { RW = 0; RS = 0; E = 0; delay(15); write_byte(0x30); delay(15); write_byte(0x30); delay(5); write_byte(0x30); delay(5); write_byte(0x38); write_byte(0x08); write_byte(0x01); write_byte(0x06); write_byte(0x0c); } ? void display(float temp, float humi) //顯示溫濕度值 { uchar i; uchar temp_str[5]; uchar humi_str[5]; //轉(zhuǎn)化為字符串 sprintf(temp_str, "%.1f", temp); sprintf(humi_str, "%.1f", humi); //顯示溫度 RS = 0; E = 1; P1 = 0x80; //第一行第一個字符 E = 0; RS = 1; for(i=0; i< 5; i++) { E = 1; P1 = temp_str[i]; E = 0; } //顯示濕度 RS = 0; E = 1; P1 = 0xc0; //第二行第一個字符 E = 0; RS = 1; for(i=0; i< 5; i++) { E = 1; P1 = humi_str[i]; E = 0; } } ? void main() { init_sht30(); //SHT30初始化 init_lcd(); //液晶屏初始化 while(1) { measure(); //測量溫濕度值并通過串口發(fā)送 delay(1000); display(temp, humi); //顯示溫濕度值 } } ?
審核編輯:湯梓紅
標簽:
媒體周日報道稱,知情人士稱透露,制藥商阿斯利康正在起草剝離其中國業(yè)
1、不是。2、仙魔錄65級就開始做。3、即使20級的妖魔道沒完成都可以去
6月18日,國務委員兼外長秦剛在北京同美國國務卿布林肯舉行會談。秦剛
直播吧6月19日訊《太陽報》報道,某支英超球隊的老板被指控在數(shù)年前強
1、小米數(shù)字系列中,最高支持55W快充的是小米11。2、小米11支持5W有線
前幾天出門散步,和朋友追跑打逗的時候(怪我太皮),手不小心按在灌木
前不久,始終將用戶放在心里的奇瑞,以“真誠與厚道”為約,用一場接地
1、失代償期肝硬化40年能活多久不取決于多少年,主要取決于失代償期肝
1、《爸爸》著實讓我艷驚了一小把,歌詞寫得細膩,聽歌的時候恍惚覺得
6月16日,全球知名輪胎制造商錦湖輪胎在位于天津的中國研發(fā)中心舉辦名
全球報道:打卡!新網(wǎng)紅墻更紅了
6月18日,大學路與魚山路交界處的網(wǎng)紅墻前站滿了前來拍照的游客們。經(jīng)
靜音降噪,向“炸街車”說不!嶗山交
隨著島城中高考結(jié)束、氣溫持續(xù)升高,市民夜間游玩、兜風、騎行活動增加
讓每朵“小葵花”向陽綻放!青島市困
為建立完善困境未成年人心理健康服務體系,促進全市困境未成年人實現(xiàn)個
青島今天多云間晴 市區(qū)最高氣溫25℃
青島市氣象臺18日06時發(fā)布:【青島市區(qū)】今天白天,多云間晴,東到東南
活力“1+3”開啟幸福之旅!青島城陽2
6月17日晚,青島市城陽區(qū)2023年市民歡樂匯正式拉開帷幕。本次開幕活動
第十三屆中國國際商標品牌節(jié)在莞舉辦
文 羊城晚報全媒體記者李洪寶圖 羊城晚報全媒體記者王俊偉第十三屆中國
福特汽車董事長:美國在電動汽車領域
今年2月,福特宣布計劃投資35億美元(IT之家備注:當前約249 55億元人
全球熱資訊!深圳:搶抓新能源汽車產(chǎn)
2023粵港澳大灣區(qū)車展在深圳舉辦,近千款車型集中亮相文 羊城晚報全媒
世界觀速訊丨廣州市增城區(qū)氣象臺發(fā)布
【增城區(qū)正果鎮(zhèn)暴雨黃色預警】受加強的雷雨云團影響,預計未來1小時正
今熱點:甚至沒包含一個首輪簽!你認
直播吧6月19日訊?據(jù)名記Shams報道,消息人士透露,奇才將比爾交易至太
環(huán)球最資訊丨經(jīng)濟日報金觀平:確保就
要立足當下,搶抓關鍵期,穩(wěn)存量、擴增量、提質(zhì)量,全力確保就業(yè)形勢總
熱記:比爾也很樂意加盟熱火 他沒有
直播吧6月19日訊?據(jù)名記Shams報道,消息人士透露,奇才將比爾交易至太
大科學裝置探索宇宙奧秘
江門中微子實驗位于廣東省江門開平市,是由中科院和廣東省共同建設的大
主題教育進行時|廣州市委巡回指導組
主題教育開展以來,市委巡回指導組切實增強做好督促指導工作的思想自覺
環(huán)球?qū)崟r:生物高分子 第4卷_關于生
生物高分子第4卷,關于生物高分子第4卷介紹這個很多人還不知道,我們一
頭條:專項計劃定向培養(yǎng)中小學教師
專項計劃定向培養(yǎng)中小學教師,主流媒體,山西門戶。山西新聞網(wǎng)是經(jīng)國務院
全球速看:生物高分子 第3a卷_關于
生物高分子第3a卷,關于生物高分子第3a卷介紹這個很多人還不知道,我們
全球滾動:“因公益鋼琴聚在一起,我
不久前,一名建筑工人在深圳街頭即興彈奏鋼琴的視頻走紅網(wǎng)絡。街頭為何
交通基礎設施網(wǎng)絡“補短板”
交通基礎設施網(wǎng)絡“補短板”,主流媒體,山西門戶。山西新聞網(wǎng)是經(jīng)國務院
【奮發(fā)有為推動高質(zhì)量發(fā)展】我省發(fā)布
【奮發(fā)有為推動高質(zhì)量發(fā)展】我省發(fā)布工業(yè)領域碳達峰實施方案,主流媒體,
環(huán)球速訊:Woj:奇才交易比爾是為開
據(jù)名記Shams、Woj報道,消息人士透露,奇才將會將比爾交易至太陽,換回
天天百事通!美記:比爾上周末分別與
直播吧6月19日訊?據(jù)名記Shams、Woj報道,消息人士透露,奇才將會將比
生物高分子 第2卷_關于生物高分子
生物高分子第2卷,關于生物高分子第2卷介紹這個很多人還不知道,我們一
生物高分子 第8卷_關于生物高分子
生物高分子第8卷,關于生物高分子第8卷介紹這個很多人還不知道,我們一
世界焦點!推動黃金珠寶時尚產(chǎn)業(yè)數(shù)字
6月15日,東方意象(中國)時尚盛典開幕。模特們穿戴時尚珠寶走秀。組委
生物高分子:微生物合成的原理與實踐
生物高分子:微生物合成的原理與實踐,關于生物高分子:微生物合成的原
省公安廳交管局發(fā)布端午節(jié)假期道路交
省公安廳交管局發(fā)布端午節(jié)假期道路交通安全提示,主流媒體,山西門戶。山
信宜市氣象臺發(fā)布雷雨大風黃色預警【
【信宜雷雨大風黃色預警】預計,受強對流云團影響,我市6時到10時有雷
環(huán)球熱推薦:美記:需密切關注追夢可
據(jù)美媒FiveReasonsSports(熱火相關消息較準確)記者EthanJ Skolnick與
我省第九次旅發(fā)大會策劃與執(zhí)行采購項
我省第九次旅發(fā)大會策劃與執(zhí)行采購項目完成招標,主流媒體,山西門戶。山