#include "dht.h" #include <avr/io.h> // Флаг прерывания volatile unsigned char interrupt_flag = 1; bool dht_done = false; int dht_check_icp; uint8_t dht_state, dht_last_state; int T1time, dPos, dNum; float temperature, humidity; float last_temperature, last_humidity; unsigned char data[5]; uint16_t dt[48]; int dtcnt; bool dht_check_act = false; // Таймер для задержки volatile unsigned int timer_counter = 0; int dht_en_timer = 0; //---------------------------------------------------------------------------------------------------- // Установка таймера void setup_timer(void) { // Настраиваем таймер 1 в режиме CTC TCCR0B = 0b00000101; // Устанавливаем значение сравнения для частоты 1 Гц OCR0A = 250; // Разрешаем прерывание сравнения A TIMSK0 |= (1 << OCIE0A); // Настраиваем таймер 1 в режиме CTC TCCR1A = 0b00000000; TCCR1B = 0b00000000; // Устанавливаем значение сравнения для частоты 1 Гц OCR1A = 250; // Разрешаем прерывание сравнения A TIMSK1 = 0b00100010; } //---------------------------------------------------------------------------------------------------- bool dht_check( void ) { if (dht_check_act) { dht_check_act = false; //-----[ 01. Старт, выжидание 18мс ]----- if ( interrupt_flag == 1) { // Запускаем таймер на 18 мс посылка start на dht DHT_DDR |= (1 << DHT_BIT); // Пин как выход DHT_PORT &= ~(1 << DHT_BIT); // Выход ноль TCNT1 = 0; // OCR1A = 288; // TCCR1A = 0b00000000; // TIMSK1 = 0b00000010; TCCR1B = 0b00000101; } // Настройка таймера для захвата времени таймером T1 if ( interrupt_flag == 2) { DHT_PORT |= (1 << DHT_BIT); // Пин в 1цу DHT_DDR &= ~(1 << DHT_BIT); // Пин порта на вход TCNT1 = 0; // Сброс значения счётчика таймера OCR1A = 10000; TCCR1A = 0b00000000; // TCCR1B = 0b10000001; // 1<<ICNC1 Антидребезг, 1<<CS10 Делитель таймера 1:1, TIFR1 = 0b00000000; // TIMSK1 = 0b00100010; // 1<<ICF1 Прерывание по захвату, 1<<OCF1A Совпадение канал A } } return DHT_check_data(); } //------------------------------------------------------------------------ float dht_humidity() { return humidity; } //------------------------------------------------------------------------ float dht_temperature() { return temperature; } //------------------------------------------------------------------------ void DHT_get_bit(){ dtcnt++; dt[ dtcnt ] = ICR1; } //------------------------------------------------------------------------ bool DHT_check_data(){ if ( dtcnt == 43 ){ dtcnt = 0; // dPos = 7; // dNum = 0; /* Цикл анализа принятых данных dt[] и распределение бит по байтам data[] */ for ( uint8_t i=4; i<44;i++){ if ( dt[ i ]<1500 ) // если время dt[i] < 1500 то data[dNum][dPos] = 0, иначе =1 { data[dNum] &= ~(1<<dPos); } // 0 else { data[dNum] |= (1<<dPos); } // 1 dPos--; if ( dPos < 0) // если прошли 8бит, то пишем в следующий байт { dPos=7; dNum++; } } DHT_DDR |= (1 << DHT_BIT); // Пин как выход DHT_PORT |= (1 << DHT_BIT); // Выход HIGH temperature = (data[3] * 0.1) + ((data[2] & 0b01111111) * 25.6); if (data[2] & 0b10000000) temperature *= -1; humidity = (data[1] * 0.1) + (data[0] * 25.6); return true; } return false; } //------------------------------------------------------------------------ void T0_CA(){ TCNT0 = 0; dht_en_timer++; if ( dht_en_timer >= 65) { dht_en_timer =0; dht_done = false; dtcnt=0; interrupt_flag = 1; dht_check_act = true; DHT_DDR |= (1 << DHT_BIT); // Пин как выход DHT_PORT |= (1 << DHT_BIT); // Выход HIGH } } //------------------------------------------------------------------------ void T1_CA(){ TCNT1 = 0; dht_check_act = true; TCCR1B = 0b00000000; if ( interrupt_flag < 3 ) { interrupt_flag++; } }