STM8單片機(jī)讀取DHT11溫濕度傳感器


STM8單片機(jī)讀取DHT11溫濕度傳感器
一、引言
隨著物聯(lián)網(wǎng)技術(shù)的發(fā)展,各類傳感器在智能家居、氣象監(jiān)測、環(huán)境監(jiān)控等領(lǐng)域得到了廣泛的應(yīng)用。溫濕度傳感器是其中重要的一類傳感器,它能夠?qū)崟r(shí)檢測環(huán)境的溫度和濕度數(shù)據(jù)。DHT11是一款常見的數(shù)字式溫濕度傳感器,具有體積小、功耗低、價(jià)格便宜等優(yōu)點(diǎn),廣泛應(yīng)用于氣象站、智能家居、倉庫環(huán)境監(jiān)控等場景。STM8系列單片機(jī)作為ST公司推出的一款低功耗、高性能的微控制器,廣泛應(yīng)用于工業(yè)控制、家居自動化和物聯(lián)網(wǎng)設(shè)備中。本篇文章將詳細(xì)介紹如何使用STM8單片機(jī)讀取DHT11溫濕度傳感器的數(shù)據(jù),包括硬件連接、軟件編程及其實(shí)現(xiàn)原理。
二、DHT11溫濕度傳感器介紹
DHT11是一款數(shù)字式溫濕度傳感器,通過單線數(shù)字信號輸出溫濕度數(shù)據(jù)。它內(nèi)部集成了溫度和濕度的傳感器單元、A/D轉(zhuǎn)換器、單片機(jī)控制電路等,因此用戶只需讀取其輸出的數(shù)字信號即可獲得對應(yīng)的溫度和濕度值。
DHT11的主要參數(shù):
測量范圍:溫度:0-50°C,濕度:20%-90% RH
精度:溫度±2°C,濕度±5% RH
輸出形式:單總線數(shù)字信號
工作電壓:3.5V至5.5V
DHT11通過單總線協(xié)議與主控設(shè)備(如STM8單片機(jī))通信,通過一根數(shù)據(jù)線發(fā)送溫濕度數(shù)據(jù)。數(shù)據(jù)傳輸時(shí),數(shù)據(jù)包包含溫度、濕度的整數(shù)和小數(shù)部分,以及校驗(yàn)和。
三、STM8單片機(jī)概述
STM8單片機(jī)是意法半導(dǎo)體(STMicroelectronics)推出的一系列8位微控制器,具有豐富的外設(shè)、低功耗和高性價(jià)比的特點(diǎn)。STM8單片機(jī)采用STM8內(nèi)核,支持多種通信協(xié)議,包括I2C、SPI、UART等,且具有多個(gè)定時(shí)器、PWM輸出、模擬輸入等功能。STM8系列單片機(jī)廣泛應(yīng)用于家庭自動化、工業(yè)控制、汽車電子等領(lǐng)域。
STM8系列單片機(jī)的關(guān)鍵特點(diǎn):
內(nèi)核:8位,時(shí)鐘頻率最大可達(dá)24MHz
內(nèi)存:多種內(nèi)存配置,從1KB Flash到64KB Flash不等
外設(shè):支持I2C、SPI、UART、GPIO等多種外設(shè)接口
功耗:低功耗設(shè)計(jì),適合電池供電應(yīng)用
四、硬件連接
要使用STM8單片機(jī)讀取DHT11溫濕度傳感器,首先需要完成硬件連接。DHT11傳感器的工作電壓為3.5V至5.5V,而STM8單片機(jī)一般工作在3.3V或5V電壓下。為了簡化接線和避免電壓不匹配,我們可以直接將DHT11傳感器的VCC腳連接到STM8的5V引腳,GND腳連接到STM8的GND引腳,數(shù)據(jù)腳連接到STM8的GPIO引腳(如PA0)。
DHT11的引腳說明:
VCC:電源引腳,接5V電源
GND:地引腳,接地
DATA:數(shù)據(jù)引腳,傳輸溫濕度數(shù)據(jù)
NC:未連接
硬件連接如下:
DHT11 VCC → STM8 5V引腳
DHT11 GND → STM8 GND引腳
DHT11 DATA → STM8 GPIO引腳(如PA0)
此外,DHT11傳感器與STM8單片機(jī)之間通過單總線協(xié)議進(jìn)行數(shù)據(jù)通信,因此,數(shù)據(jù)線連接的GPIO引腳需要支持?jǐn)?shù)字輸入輸出(如PA0、PB0等)。在接線過程中,建議在DHT11的數(shù)據(jù)引腳和STM8的數(shù)據(jù)引腳之間串聯(lián)一個(gè)4.7kΩ的上拉電阻,以確保數(shù)據(jù)傳輸?shù)姆€(wěn)定性。
五、軟件設(shè)計(jì)
STM8單片機(jī)讀取DHT11傳感器的數(shù)據(jù)需要通過GPIO引腳與DHT11進(jìn)行通信。DHT11通過一種特殊的單總線協(xié)議與外部設(shè)備交換數(shù)據(jù),數(shù)據(jù)傳輸包括以下幾個(gè)步驟:發(fā)送起始信號、傳輸溫濕度數(shù)據(jù)、校驗(yàn)和校驗(yàn)。我們將逐步解析如何通過STM8單片機(jī)編寫程序來完成這一過程。
1. 初始化
在程序開始時(shí),我們首先需要初始化STM8的GPIO引腳。以PA0為數(shù)據(jù)傳輸引腳,我們需要將其配置為輸出模式,并發(fā)送一個(gè)起始信號來啟動數(shù)據(jù)傳輸。
// 初始化GPIO引腳為輸出模式
GPIO_Init(GPIOA, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
2. 發(fā)送起始信號
DHT11傳感器要求主機(jī)發(fā)送一個(gè)至少18ms的低電平信號,作為起始信號。在STM8單片機(jī)上,我們可以通過延時(shí)函數(shù)實(shí)現(xiàn)這一要求。
// 發(fā)送起始信號,拉低PA0引腳18ms
GPIO_ResetBits(GPIOA, GPIO_PIN_0);
Delay_ms(20); // 延時(shí)20ms
GPIO_SetBits(GPIOA, GPIO_PIN_0); // 拉高PA0引腳
3. 等待DHT11響應(yīng)
DHT11傳感器收到起始信號后,會等待一定時(shí)間并響應(yīng)。它會通過將數(shù)據(jù)引腳拉低80微秒,然后再拉高80微秒的方式向主機(jī)發(fā)送響應(yīng)信號。我們需要用STM8單片機(jī)檢測DHT11的響應(yīng)信號。
// 等待DHT11響應(yīng)信號
GPIO_Init(GPIOA, GPIO_PIN_0, GPIO_MODE_IN_FL_NO_IT); // 配置PA0為輸入模式
while (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == RESET); // 等待引腳從低電平變?yōu)楦唠娖?br/>
4. 讀取數(shù)據(jù)
DHT11通過一系列的高低電平脈沖傳輸8位數(shù)據(jù)。每個(gè)數(shù)據(jù)位由一個(gè)50微秒的高電平和一個(gè)可變長度的低電平組成。如果低電平的時(shí)長大于26微秒,表示該位為1,否則為0。我們需要用定時(shí)器或延時(shí)函數(shù)來測量低電平的時(shí)長,判斷每一位的數(shù)據(jù)。
uint8_t ReadByte(void) {
uint8_t byte = 0;
for (int i = 0; i < 8; i++) {
// 等待低電平結(jié)束
while (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == RESET);
// 等待高電平
TimerStart();
while (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == SET);
// 計(jì)算高電平時(shí)長,判斷是0還是1
if (TimerElapsed() > 40) { // 判斷高電平持續(xù)時(shí)間
byte |= (1 << (7 - i)); // 設(shè)置為1
}
}
return byte;
}
5. 校驗(yàn)和
DHT11數(shù)據(jù)傳輸完成后,會發(fā)送一個(gè)校驗(yàn)和,校驗(yàn)和是前面?zhèn)鬏數(shù)臐穸群蜏囟葦?shù)據(jù)字節(jié)按位相加的低8位。我們需要對接收到的數(shù)據(jù)進(jìn)行校驗(yàn),確保數(shù)據(jù)的正確性。
uint8_t checksum = humidity1 + humidity2 + temperature1 + temperature2;
if (checksum != checksum_received) {
// 校驗(yàn)失敗,重新讀取數(shù)據(jù)
}
6. 完整程序
完整的程序代碼包括初始化、數(shù)據(jù)傳輸、數(shù)據(jù)讀取和校驗(yàn)等部分。通過程序,我們可以實(shí)現(xiàn)從DHT11傳感器讀取溫度和濕度數(shù)據(jù),并在串口輸出。
#include "stm8s.h"
// 延時(shí)函數(shù)
void Delay_ms(uint16_t ms) {
while (ms--) {
for (int i = 0; i < 1000; i++);
}
}
// 讀取數(shù)據(jù)
uint8_t ReadByte(void) {
uint8_t byte = 0;
for (int i = 0; i < 8; i++) {
// 等待低電平結(jié)束
while (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == RESET);
// 等待高電平
TimerStart();
while (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == SET);
// 計(jì)算高電平時(shí)長,判斷是0還是1
if (TimerElapsed() > 40) {
byte |= (1 << (7 - i));
}
}
return byte;
}
int main(void) {
uint8_t humidity1,uint8_t humidity2, temperature1, temperature2, checksum;
// 初始化GPIO
GPIO_Init(GPIOA, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST); // 配置PA0為推挽輸出
while (1) {
// 發(fā)送起始信號
GPIO_ResetBits(GPIOA, GPIO_PIN_0); // 拉低PA0
Delay_ms(20); // 延時(shí)20ms,DHT11要求至少18ms
GPIO_SetBits(GPIOA, GPIO_PIN_0); // 拉高PA0
// 等待DHT11響應(yīng)
GPIO_Init(GPIOA, GPIO_PIN_0, GPIO_MODE_IN_FL_NO_IT); // 配置PA0為輸入
while (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == RESET); // 等待PA0從低電平變?yōu)楦唠娖?br/> while (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == SET); // 等待高電平結(jié)束
// 讀取濕度數(shù)據(jù)
humidity1 = ReadByte();
humidity2 = ReadByte();
// 讀取溫度數(shù)據(jù)
temperature1 = ReadByte();
temperature2 = ReadByte();
// 讀取校驗(yàn)和
checksum = ReadByte();
// 校驗(yàn)數(shù)據(jù)
if (checksum == (humidity1 + humidity2 + temperature1 + temperature2)) {
// 輸出溫度和濕度數(shù)據(jù)
printf("Humidity: %d.%d%%, Temperature: %d.%d°C
", humidity1, humidity2,
temperature1, temperature2);
} else {
// 校驗(yàn)和錯(cuò)誤,重新讀取
printf("Data error, retrying...
");
}
// 延時(shí)1秒鐘
Delay_ms(1000);
}
}
六、程序解析
在上述代碼中,我們進(jìn)行了如下操作:
GPIO初始化:
我們將STM8的PA0引腳設(shè)置為推挽輸出模式,用來發(fā)送信號給DHT11。
在接收數(shù)據(jù)時(shí),將PA0設(shè)置為輸入模式,讀取DHT11傳輸?shù)臄?shù)據(jù)。
發(fā)送起始信號:
通過將PA0拉低并保持20ms以上,我們向DHT11傳感器發(fā)送起始信號。這是DHT11開始數(shù)據(jù)傳輸?shù)谋匾獥l件。
等待DHT11響應(yīng):
DHT11在收到起始信號后,會先將數(shù)據(jù)線拉低80μs,然后拉高80μs,表示準(zhǔn)備好傳輸數(shù)據(jù)。程序通過檢測PA0的電平變化來判斷DHT11是否準(zhǔn)備好響應(yīng)。
讀取數(shù)據(jù):
DHT11通過一系列高低電平脈沖傳輸8位數(shù)據(jù)。每個(gè)數(shù)據(jù)位的傳輸方式是:首先一個(gè)50μs的高電平,然后緊接著一個(gè)長度可變的低電平。若低電平時(shí)間超過26μs,則表示這一位是1;否則是0。
為了確保數(shù)據(jù)的正確性,我們讀取濕度、溫度和校驗(yàn)和數(shù)據(jù)。
數(shù)據(jù)校驗(yàn):
在讀取到濕度、溫度和校驗(yàn)和數(shù)據(jù)后,我們通過計(jì)算濕度和溫度字節(jié)之和,來驗(yàn)證數(shù)據(jù)的有效性。如果校驗(yàn)和匹配,說明數(shù)據(jù)正確,可以進(jìn)行后續(xù)處理;如果校驗(yàn)和不匹配,則重新獲取數(shù)據(jù)。
輸出數(shù)據(jù):
如果數(shù)據(jù)驗(yàn)證成功,程序會通過串口輸出溫濕度數(shù)據(jù)。在此程序中,我們通過
printf
函數(shù)將結(jié)果打印到終端或調(diào)試工具。延時(shí):
為了防止頻繁讀取,程序每隔1秒重新讀取一次DHT11傳感器數(shù)據(jù)。
七、常見問題及解決方案
在實(shí)際應(yīng)用中,可能會遇到一些常見的問題,如數(shù)據(jù)不準(zhǔn)確、無法讀取數(shù)據(jù)或校驗(yàn)和錯(cuò)誤等。以下是一些常見問題及解決方案:
數(shù)據(jù)傳輸不穩(wěn)定:
如果數(shù)據(jù)傳輸過程中出現(xiàn)丟包或錯(cuò)誤,可能是因?yàn)閭鞲衅髋cSTM8之間的連線不穩(wěn)定。檢查數(shù)據(jù)線的連接,確保DHT11的VCC和GND引腳正確連接,并且數(shù)據(jù)引腳沒有松動。
在數(shù)據(jù)線和STM8之間添加一個(gè)4.7kΩ的上拉電阻,這對于確保穩(wěn)定的數(shù)據(jù)傳輸非常重要。
數(shù)據(jù)校驗(yàn)失?。?/strong>
如果校驗(yàn)和驗(yàn)證失敗,可能是由于DHT11傳輸過程中發(fā)生了干擾或數(shù)據(jù)丟失。在這種情況下,可以嘗試增加延遲時(shí)間,或通過軟件重試機(jī)制來確保數(shù)據(jù)完整性。
讀取速度過快:
DHT11每次讀取后需要一定時(shí)間的冷卻期。通常,DHT11每秒只能提供一次測量數(shù)據(jù),因此不建議每隔太短的時(shí)間讀取傳感器數(shù)據(jù)。增加讀取間隔時(shí)間可以提高穩(wěn)定性。
溫濕度數(shù)據(jù)不準(zhǔn)確:
DHT11的精度較低,尤其在高濕度或低溫度環(huán)境中,測量的準(zhǔn)確度可能會有所下降。如果需要更高精度的溫濕度數(shù)據(jù),可以考慮使用其他傳感器,如DHT22。
八、總結(jié)
本篇文章詳細(xì)介紹了如何使用STM8單片機(jī)讀取DHT11溫濕度傳感器的數(shù)據(jù)。我們從硬件連接、軟件編程、數(shù)據(jù)讀取到數(shù)據(jù)校驗(yàn)等方面進(jìn)行了詳細(xì)的講解。STM8單片機(jī)通過GPIO引腳與DHT11傳感器進(jìn)行單總線通信,完成了溫濕度數(shù)據(jù)的獲取與校驗(yàn),并通過串口輸出到終端。
在實(shí)際應(yīng)用中,DHT11傳感器具有較低的精度和測量范圍,適合用于一些低成本的項(xiàng)目。若需要更高精度的溫濕度數(shù)據(jù),可以考慮使用DHT22、SHT21等更高性能的傳感器。通過掌握這項(xiàng)技術(shù),您可以將STM8單片機(jī)與各種傳感器連接,構(gòu)建更多智能應(yīng)用,提升物聯(lián)網(wǎng)項(xiàng)目的效果和效率。
責(zé)任編輯:David
【免責(zé)聲明】
1、本文內(nèi)容、數(shù)據(jù)、圖表等來源于網(wǎng)絡(luò)引用或其他公開資料,版權(quán)歸屬原作者、原發(fā)表出處。若版權(quán)所有方對本文的引用持有異議,請聯(lián)系拍明芯城(marketing@iczoom.com),本方將及時(shí)處理。
2、本文的引用僅供讀者交流學(xué)習(xí)使用,不涉及商業(yè)目的。
3、本文內(nèi)容僅代表作者觀點(diǎn),拍明芯城不對內(nèi)容的準(zhǔn)確性、可靠性或完整性提供明示或暗示的保證。讀者閱讀本文后做出的決定或行為,是基于自主意愿和獨(dú)立判斷做出的,請讀者明確相關(guān)結(jié)果。
4、如需轉(zhuǎn)載本方擁有版權(quán)的文章,請聯(lián)系拍明芯城(marketing@iczoom.com)注明“轉(zhuǎn)載原因”。未經(jīng)允許私自轉(zhuǎn)載拍明芯城將保留追究其法律責(zé)任的權(quán)利。
拍明芯城擁有對此聲明的最終解釋權(quán)。