Tüm projeler
06Hazır
Sıcaklık ve Nem
DHT11'den tek hat protokolle sıcaklık ve nem oku.
1-Wire
01
Ne öğrenirsin
Zamanlamaya duyarlı tek-hat haberleşme: sen komut verirsin, sensör 40 biti darbe uzunluklarıyla geri gönderir. Her biti bir timer ile çözersin.
02
Gereken parçalar
03
Bağlantı
| Modül | Kart | Not |
|---|---|---|
| + / VCC | 3.3V | DATA da 3.3V olur, güvenli. |
| OUT / DATA | PA2 | Tek yönlü değil — çift yönlü hat |
| - / GND | GND | — |
04
Kod
main.c
1#include <stdint.h>2#include <stdbool.h>3#include "inc/hw_memmap.h"4#include "driverlib/sysctl.h"5#include "driverlib/gpio.h"6#include "driverlib/timer.h"7 8#define LED_ALL (GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3)9#define DHT_PORT GPIO_PORTA_BASE10#define DHT_PIN GPIO_PIN_2 // PA211#define PWM_STEPS 25612 13static void showColor(uint8_t r, uint8_t g, uint8_t b, uint32_t periods) {14 volatile uint32_t p, i;15 for (p = 0; p < periods; p++)16 for (i = 0; i < PWM_STEPS; i++) {17 uint8_t out = 0;18 if (i < r) out |= GPIO_PIN_1;19 if (i < g) out |= GPIO_PIN_3;20 if (i < b) out |= GPIO_PIN_2;21 GPIOPinWrite(GPIO_PORTF_BASE, LED_ALL, out);22 SysCtlDelay(2);23 }24}25 26static void delayMs(uint32_t ms) { SysCtlDelay((SysCtlClockGet() / 3000) * ms); }27static void delayUs(uint32_t us) { SysCtlDelay((SysCtlClockGet() / 3000000) * us); }28 29static void dhtPinOut(void) { GPIOPinTypeGPIOOutput(DHT_PORT, DHT_PIN); }30static void dhtPinIn(void) {31 GPIOPinTypeGPIOInput(DHT_PORT, DHT_PIN);32 GPIOPadConfigSet(DHT_PORT, DHT_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);33}34static int dhtLevel(void) { return GPIOPinRead(DHT_PORT, DHT_PIN) ? 1 : 0; }35 36// Read 5 bytes from the DHT11. Returns 1 on success, 0 on error/timeout.37static int dhtRead(uint8_t data[5]) {38 uint32_t i, start, us, timeout;39 for (i = 0; i < 5; i++) data[i] = 0;40 41 dhtPinOut(); // start: hold low >= 18 ms42 GPIOPinWrite(DHT_PORT, DHT_PIN, 0);43 delayMs(20);44 GPIOPinWrite(DHT_PORT, DHT_PIN, DHT_PIN);45 delayUs(30);46 dhtPinIn();47 48 timeout = 100000; while (dhtLevel() != 0) if (--timeout == 0) return 0; // ack low49 timeout = 100000; while (dhtLevel() == 0) if (--timeout == 0) return 0; // ack high50 timeout = 100000; while (dhtLevel() != 0) if (--timeout == 0) return 0; // bit0 low51 52 for (i = 0; i < 40; i++) {53 timeout = 100000; while (dhtLevel() == 0) if (--timeout == 0) return 0; // 50us low ends54 start = TimerValueGet(TIMER0_BASE, TIMER_A);55 timeout = 100000; while (dhtLevel() != 0) if (--timeout == 0) return 0; // measure high56 us = (TimerValueGet(TIMER0_BASE, TIMER_A) - start) / 50; // 50 MHz -> us57 data[i / 8] <<= 1;58 if (us > 45) data[i / 8] |= 1; // long high = 159 }60 if ((uint8_t)(data[0] + data[1] + data[2] + data[3]) != data[4]) return 0; // checksum61 return 1;62}63 64int main(void) {65 SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL |66 SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);67 68 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);69 while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)) {}70 GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LED_ALL);71 72 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);73 while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)) {}74 dhtPinIn();75 76 SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // free-running us timer77 while (!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0)) {}78 TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);79 TimerLoadSet(TIMER0_BASE, TIMER_A, 0xFFFFFFFF);80 TimerEnable(TIMER0_BASE, TIMER_A);81 82 while (1) {83 uint8_t d[5];84 if (dhtRead(d)) {85 int32_t tmp = d[2]; // d[0]=humidity%, d[2]=temp C86 if (tmp < 18) tmp = 18; // map 18..40 C87 if (tmp > 40) tmp = 40;88 int32_t lv = ((tmp - 18) * 255) / 22; // 0..25589 if (lv < 128) showColor(0, lv * 2, 255 - lv * 2, 40); // cool -> blue90 else showColor((lv - 128) * 2, 255 - (lv - 128) * 2, 0, 40); // warm -> red91 } else {92 showColor(60, 25, 0, 10); // read failed -> amber blink93 showColor(0, 0, 0, 5);94 }95 delayMs(1500); // DHT11 is slow: >= 1 s between reads96 }97}05
Çıktı
Aşağıdaki simülasyon tarayıcında çalışır — gerçek kartın davranışını taklit eder.
- sıcaklık
- 24 °C
- nem
- 45 %