unsigned char data[5]; static float temperature, humidity; float value; #define F_CPU 16000000UL ISR(TIMER1_OVF_vect) // процедура обработки прерывания переполнения счетчика { TCNT1 = value; // preload timer } void timer_set(float value_1, byte Dev) { TCCR1A = 0; TCCR1B = 0; TCNT1 = value_1; // preload timer TCCR1B |= Dev; // (коэффициент деления предделителя) TIMSK1 |= (1 << TOIE1); //(разрешаем вызов процедуры обработки прерывания переполнения счетчика) interrupts(); // разрешаем все прерывания value = value_1; } void DHT22_setup() { #define DHT_PORT PORTD #define DHT_DDR DDRD #define DHT_PIN PIND #define DHT_BIT 4 //по ардуиновски D5 Serial.begin(9600); } unsigned int read_dht_hum() //подпрограмма работы с DHT { int temp; unsigned char i, j; ReLoad: //метка для ошибок //=============MCU send START DHT_DDR |= (1 << DHT_BIT); //выход DHT_PORT &= ~(1 << DHT_BIT); //низкий уровень, подтягиваем линию, разбудим датчик delayEquivalent2(18); //18 мс по условиям документации. DHT_PORT |= (1 << DHT_BIT); //отпускаем линию DHT_DDR &= ~(1 << DHT_BIT); //пин как выход //============= инциализация DHT delayEquivalent3(1); //задержка по условию if (DHT_PIN &(1 << DHT_BIT)) { Serial.println("NO init "); goto ReLoad; } //датчик должен ответить 0 delayEquivalent4(0.99); //по истечению 80 мкс, датчик должен отпустить шину //===============Приём 40 бит данных while (DHT_PIN &(1 << DHT_BIT)); //ждем пока на шине появится 1 for (j = 0; j < 5; j++) //цикл для 0-4 байт { data[j] = 0; for (i = 0; i < 8; i++) //приём битов и укладка их в байты { while (!(DHT_PIN &(1 << DHT_BIT))); //ждем когда датчик отпустит шину delayEquivalent5(0.99); //задержка высокого уровня при 0 30 мкс if (DHT_PIN &(1 << DHT_BIT)) //если по истечению времени сигнал на линии высокий, значит передается 1 data[j] |= 1 << (7 - i); //тогда i-й бит устанавливаем 1 while (DHT_PIN &(1 << DHT_BIT)); // ждем окончание 1 } } if ((unsigned char)(data[0] + data[1] + data[2] + data[3]) != data[4]) //checksum { Serial.println("checksum Error "); goto ReLoad; } } //конец подрограммы void delayEquivalent2(uint8_t delayTime)//Для 18 Милисеунд { for(volatile uint8_t i1 = 0; i1 < 10; ++i1) { for(volatile uint8_t i2 = 0; i2 < 100; ++i2) { for(volatile uint8_t i3 = 0; i3 < delayTime; ++i3) { } } } } void delayEquivalent3(uint8_t delayTime1)//Для 50 микросекунд { for(volatile uint8_t i1 = 0; i1 < 10; ++i1) { for(volatile uint8_t i2 = 0; i2 < 5; ++i2) { for(volatile uint8_t i3 = 0; i3 < delayTime1; ++i3) { } } } } void delayEquivalent4(uint8_t delayTime2)//Для 80 микросекунд { for(volatile uint8_t i1 = 0; i1 < 10; ++i1) { for(volatile uint8_t i2 = 0; i2 < 8; ++i2) { for(volatile uint8_t i3 = 0; i3 < delayTime2; ++i3) { } } } } void delayEquivalent5(uint8_t delayTime3)//Для 80 микросекунд { for(volatile uint8_t i1 = 0; i1 < 10; ++i1) { for(volatile uint8_t i2 = 0; i2 < 3; ++i2) { for(volatile uint8_t i3 = 0; i3 < delayTime3; ++i3) { } } } } int get_DHT_value_temperature() { read_dht_hum(); //вызов подпрограммы DHT11 temperature = (data[3] *0.1) + ((data[2] &0b01111111) *25.6); //нюанс расчета температуры для DHT22 if (data[2] &0b10000000) temperature *= -1; //если отрицательная температура timer_set(0, 4); //хватает задержки в 1 сек, для этого скетча хватает скорости 180 return temperature; } int get_DHT_value_humidity() { read_dht_hum(); //вызов подпрограммы DHT11 humidity = (data[1] *0.1) + (data[0] *25.6); //нюанс расчета влажности для DHT22 timer_set(0, 4); return humidity; }