4_Ust-vo_poluchenia_velichi.../DHT_22.c

150 lines
4.2 KiB
C
Raw 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 <avr/interrupt.h>
#include <avr/io.h>
// Определения портов и битов
#define DHT_PORT PORTD
#define DHT_DDR DDRD
#define DHT_PIN PIND
#define DHT_BIT 4
// Глобальные переменные
unsigned char data[5];
float temperature, humidity;
// Флаг прерывания
volatile unsigned char interrupt_flag = 0;
// Таймер для задержки
volatile unsigned int timer_counter = 0;
// Прерывание таймера
ISR(TIMER1_COMPA_vect)
{
// Увеличиваем счетчик таймера
timer_counter++;
// Проверяем, достигли ли мы нужной задержки
if (timer_counter == 180000)
{
// Сбрасываем счетчик таймера
timer_counter = 0;
// Устанавливаем флаг прерывания
interrupt_flag = 1;
}
}
// Функция чтения данных с DHT
unsigned int read_dht_hum()
{
int temp;
unsigned char i, j;
ReLoad:
// Выставляем пин как выход и устанавливаем низкий уровень
DHT_DDR |= (1 << DHT_BIT);
DHT_PORT &= ~(1 << DHT_BIT);
// Задержка 18 мс
//timer_counter = 18000;
timer_counter = 0;
while(timer_counter < 18000) timer_counter++;
//for (volatile unsigned int i = 0; i < timer_counter; i++);
// Отпускаем линию и переводим пин как вход
DHT_PORT |= (1 << DHT_BIT);
DHT_DDR &= ~(1 << DHT_BIT);
// Задержка 50 мкс
//timer_counter = 50;
timer_counter = 0;
while(timer_counter < 50) timer_counter++;
//for (volatile unsigned int i = 0; i < timer_counter; i++);
// Проверяем, ответил ли датчик
if (DHT_PIN & (1 << DHT_BIT))
{
Serial.println("No init");
//goto ReLoad;
}
// Задержка 80 мкс
//timer_counter = 50;
timer_counter = 0;
while(timer_counter < 50) timer_counter++;
//for (volatile unsigned int i = 0; i < timer_counter; i++);
// Принимаем 40 бит данных
while (DHT_PIN & (1 << DHT_BIT));
for (j = 0; j < 5; j++)
{
data[j] = 0;
for (i = 0; i < 8; i++)
{
while (!(DHT_PIN & (1 << DHT_BIT)));
// Задержка 30 мкс
timer_counter = 0;
while(timer_counter < 30) timer_counter++;
//for (volatile unsigned int i = 0; i < timer_counter; i++);
if (DHT_PIN & (1 << DHT_BIT)) data[j] |= 1 << (7 - i);
while (DHT_PIN & (1 << DHT_BIT));
}
}
// Проверяем контрольную сумму
if ((unsigned char)(data[0] + data[1] + data[2] + data[3]) != data[4])
{
Serial.println("Check summ error");
//goto ReLoad;
}
}
// Установка таймера
void setup_timer()
{
// Настраиваем таймер 1 в режиме CTC
TCCR1A = (1 << WGM12);
TCCR1B = (1 << CS12) | (1 << WGM13);
// Устанавливаем значение сравнения для частоты 1 Гц
OCR1A = 15624;
// Разрешаем прерывание сравнения A
TIMSK1 |= (1 << OCIE1A);
}
// Настройка
void setup()
{
// Инициализируем UART
Serial.begin(9600);
// Настраиваем таймер
setup_timer();
// Разрешаем прерывания
sei();
}
// Основной цикл
void loop()
{
// Ожидаем прерывания
while (interrupt_flag);
// Сбрасываем флаг прерывания
interrupt_flag = 0;
// Читаем данные с DHT
read_dht_hum();
// Вычисляем температуру и влажность
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);
// Выводим данные на UART
Serial.print(humidity);
Serial.print("% ");
Serial.print(temperature);
Serial.println("C");
}