4_Ust-vo_poluchenia_velichi.../DHT_22.cpp

151 lines
4.7 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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++;
}
}