ATMega8 и DHT11

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Доброго времени суток!
Возникла проблема, помогите кто может ))
Собираю термометр-гигрометр на ATmega8 и DHT11, вывод на семисегментные индикаторы. Проблема в том, что данные с датчика получаются только один раз, при повторном считывании зависает, или через какой то промежуток времени, когда пытался это исправить. Я так понимаю, проблема где в отсчете секунд, для повторного опроса, но не пойму где, вроде нормально должно работать.
Прикладываю скрины из протеуса, в железе тоже самое, ну только что нет транзисторов и отображается в железе как и положено один сегмент.

Буду очень благодарен помощи, в сети в основном либо на одном семисегментнике и меняется, либо на жк. А по мне так лучше на двух, к чему это моргание и дешевле, может и еще кому пригодится, когда допилим ))

Основной код:
Спойлер

Код: Выделить всё


/ Triple_H 27.05.2020
// Индикатор с общим катодом
// Датчик на PD5


#define F_CPU 1000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <string.h>
//===================
#include "dht11.h"

//===================
#define	DIG_PORT 							PORTC
#define	DIG_DDR  							DDRC
#define	SEG_PORT 							PORTB
#define	SEG_DDR  							DDRB
#define	Digit1  							PC0
#define	Digit2  							PC1
#define	Digit3  							PC2
#define	Digit4  							PC3
#define DISPLAY_DELAY						0.2
#define SYMBOL_POINT						0b10000000
#define SYMBOL_MINUS						0b01000000
//===================
uint16_t 	ms = 0;
uint8_t 	sec = 0, min = 0, hour = 0;
uint32_t 	second_count = 0;
uint8_t 	refresh = 0;
uint8_t 	dig[4] = {0, 0, 0, 0};
uint8_t		DHT11_Temperature = DHT11_ERROR;
uint8_t		DHT11_Humidity = DHT11_ERROR;
uint32_t 	DHT11_Update_Time = 0;
//===================
// Массив для декодирования цифры в код числа для 7-сегментного индикатора
uint8_t digits[10] = {
	//hgfedcba
	0b00111111,
	0b00000110,
	0b01011011,
	0b01001111,
	0b01100110,
	0b01101101,
	0b01111101,
	0b00000111,
	0b01111111,
	0b01101111,
};
//===================
ISR(TIMER2_COMP_vect) 
{
	uint8_t sreg_save = SREG;
	ms++;
	if(ms == 100)
	{
		second_count++;
		ms = 0;
		sec++;
		if (sec == 60)
		{
			sec = 0;
			min++;
			if (min == 60)
			{
				min = 0;
				hour++;
				if (hour == 24)
				hour = 0;
			}
		}
	}
	SREG = sreg_save;
}
//===================
void DHT11_Update()
{
	DHT11_Read(&DHT11_Temperature, &DHT11_Humidity);
	DHT11_Update_Time = second_count + DHT11_REFRESH_TIME;
	refresh = 1;
}
//===================
int main (void)
{
	// Запрещаем прерывания
	cli();
	// Настраиваем порты ввода-вывода
	SEG_DDR = 0xFF;
	SEG_PORT = 0x00;
	DIG_DDR = (1 << Digit1)|(1 << Digit2)|(1 << Digit3)|(1 << Digit4);
	DIG_PORT &= ~((1 << Digit1)|(1 << Digit2)|(1 << Digit3)|(1 << Digit4));
	// Настраиваем таймеры
	// Разрешение прерывания таймера 2
	TIMSK = (1 << OCIE2);
	// Настраиваем таймер 2 на подсчет секунд
	// Предделитель на 64
	TCCR2 = (1 << WGM21)|(0 << WGM20)|(1 << CS22)|(0 << CS21)|(0 << CS20);
	OCR2 = F_CPU / 64 / 1000;
	// Обнуляем счетчик таймера 2
	TCNT2 = 0;
	// Запуск первого измерения влажности
	_delay_ms(100);
	DHT11_Update();
	// Разрешаем прерывания
	sei();
	// Основная программа
	while (1)
	{
		if(second_count >= DHT11_Update_Time)
		DHT11_Update();
		// Преобразование температуры в отдельные цифры для вывода
		if (refresh)
		{
			if (DHT11_Humidity!= DHT11_ERROR)
			{
				
		
			if (DHT11_Temperature!= DHT11_ERROR)
			{
				dig[0] = digits[DHT11_Temperature / 10];
				dig[1] = digits[DHT11_Temperature % 10];
				dig[2] = digits[DHT11_Humidity / 10];
				dig[3] = digits[DHT11_Humidity % 10];
			}
			else
			memset(dig, SYMBOL_MINUS, sizeof(dig));
			refresh = 0;
		}
		
			}
		
		DIG_PORT = (1 << Digit1);
		SEG_PORT = dig[0];
		_delay_ms(DISPLAY_DELAY);
		DIG_PORT = (1 << Digit2);
		SEG_PORT = dig[1];
		_delay_ms(DISPLAY_DELAY);
		DIG_PORT = (1 << Digit3);
		SEG_PORT = dig[2];
		_delay_ms(DISPLAY_DELAY);
		DIG_PORT = (1 << Digit4);
		SEG_PORT = dig[3];
		_delay_ms(DISPLAY_DELAY);
	}
}


Датчик:
Спойлер

Код: Выделить всё

/*
 * dht11.h
 *
 * Created: 27.05.2020 12:34:04
 *  Author: bykadorov_a
 */ 
	#pragma once

/*#ifndef DHT11_H_
#define DHT11_H_*/

//==================
#define DHT11_DDR				DDRD
#define DHT11_PIN				PIND
#define DHT11_PORT				PORTD
#define DHT11_DS				5
#define DHT11_REFRESH_TIME		5
#define DHT11_ERROR 			255
//==================
// чтение показаний из DHT11
void  DHT11_Read(uint8_t *temperature, uint8_t *humidity);



//#endif /* DHT11_H_ */


Код: Выделить всё


/*
 * dht11.c
 *
 * Created: 27.05.2020 12:37:25
 *  Author: bykadorov_a
 */ 
	#include <avr/io.h>
	#include <util/delay.h>
	#include "dht11.h"
	//==================
	void  DHT11_Read(uint8_t *temperature, uint8_t *humidity) {
		uint8_t data[5]={0,0,0,0,0};
		uint8_t i,j = 0;
		uint8_t error = 0;

		*temperature = DHT11_ERROR;
		*humidity = DHT11_ERROR;

		//reset port
		DHT11_DDR |= (1<<DHT11_DS); 					//output
		DHT11_PORT |= (1<<DHT11_DS); 					//high
		_delay_ms(100);
		//send request
		DHT11_PORT &= ~(1<<DHT11_DS); 					//low
		_delay_ms(18);
		DHT11_PORT |= (1<<DHT11_DS); 					//high
		_delay_us(1);
		DHT11_DDR &= ~(1<<DHT11_DS); 					//input
		_delay_us(39);
		//check start condition 1
		if((DHT11_PIN & (1<<DHT11_DS))) {
			error = 1;
		}
		_delay_us(80);
		//check start condition 2
		if(!(DHT11_PIN & (1<<DHT11_DS))) {
			error = 1;
		}
		_delay_us(80);
		if (!error){
			//read the data
			for (j=0; j<5; j++) { 						//read 5 byte
				uint8_t result=0;
				for(i=0; i<8; i++) {					//read every bit
					while(!(DHT11_PIN & (1<<DHT11_DS)));//wait for an high input
					_delay_us(30);
					if(DHT11_PIN & (1<<DHT11_DS)) 		//if input is high after 30 us, get result
					result |= (1<<(7-i));
					while(DHT11_PIN & (1<<DHT11_DS)); 	//wait until input get low
				}
				data[j] = result;
			}
			//reset port
			DHT11_DDR |= (1<<DHT11_DS); 				//output
			DHT11_PORT |= (1<<DHT11_DS); 				//low
			_delay_ms(100);
			//check checksum
			if ((data[0] + data[1] + data[2] + data[3]) == data[4]) {
				*temperature = data[2];
				*humidity = data[0];
			}
		}
	}


Результат в Proteus:
СпойлерИзображение Изображение
Вложения
Test-gig 8.rar
Проект в AVRStudio
(69.93 КБ) 213 скачиваний
Реклама
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Triple_H, DHT11 - очень неточный датчик, имейте в виду. Многие рекомендуют его вообще не рассматривать.
Что касается вашего кода - все глобальные переменные, что меняются в прерывании должны быть объявлены как volatile. Иначе работать не будет нормально.
Плюс сохранение-восстановление SREG - лишнее.
Реклама
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Благодарю за совет, но дело в чем то другом, пробовал с volatile, без изменений. Ну а датчик я хотел просто попробовать как там с влажностью у меня, да и сильная точность мне не нужна, будет показывать если хоть примерно уже хорошо, но на будущее учтем. еще бы с этим разобраться ((
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Ну говорят некоторые из них показывают "погоду на Марсе". Т.е. не просто неточно, а вообще бред.
volatile нужен обязательно. Проверьте что для всех переменных в прерывании его указали. Бегло в глаза бросается сразу эта ошибка (это именно ошибка, без volatile точно работать не будет). Проект подробнее посмотрю попозже.
Реклама
Эиком - электронные компоненты и радиодетали
Самсусамыч

Сообщение Самсусамыч »

Да уж, данные датчики зарекомендовали себя с не лучшей стороны… :roll: особенно те которые выдают значения в попугаях… :)) есть у меня пара таких экземпляров. :)

Тестовая прошивка для датчика DHT11. МК (ATtiny2313A), тактируется на частоте 8 МГц от внутреннего генератора. Индикатор четырёх разрядный ОА.

На индикаторе попеременно выводятся значения влажности и температуры. У влажности на крайнем правом разряде высвечивается символ «Н». При отсутствии или неисправности датчика на индикаторе будут засвечен сегмент «D» на всех разрядах.

Схема:
1.png
Прошивка:
dth11.hex
Реклама
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Да, с одним дисплеем я видел, но хотелось бы по раздельно, стабильно, а не моргало. Вот и проблема, он то датчик опрашивает, но почему то один раз, а во второй виснет. volatile добавлял, не помогает, куда только я его не добавлял, все равно не помогает ((
Реклама
Самсусамыч

Сообщение Самсусамыч »

Если всё выводить на один четырёхразрядный индикатор, то выглядит это как-то коряво… хоть и не мигает. :)

Хотя, если прикрутить кнопку и по нажатию сделать переключение, то в принципе вполне нормуль. :)
Прошивка с кнопкой (кнопка на выводе РА0):
dth11.hex
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Благодарю.
С кнопкой это уже интереснее, оставлю на запасной вариант если эту не докавыряю )) Просто интересно, почему он виснет то, датчик считывает, значит правильно на обмен с датчиком, что идет не так во второй раз ((

p. s. А вот сейчас сижу и думаю, а может с кнопкой оно и прикольнее даже ))
Самсусамыч

Сообщение Самсусамыч »

А вот если бы индикатор взять ЖКИ (к примеру WH0802), то и кнопки не надо и оба значения (влажность и температура) выведены были бы читабельно. Но это так - «мысли в слух». :)
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

не считал ноги... а просто "расширить" дисплей (увеличить количество разрядов) не вариант?
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Самсусамыч

Сообщение Самсусамыч »

Конечно вариант (зависит от задачи), но мне лично симпатизируют ЖКИ (DH44780) так как с ними удобнее… есть и цифры и буквы… да и нет необходимости выдерживать строгие интервалы как при динамической индикации. :)
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Triple_H, увеличьте частоту МК до 8МГц,
переделайте
Спойлер

Код: Выделить всё

		DIG_PORT = 0x0F & (~(1 << Digit1));
		SEG_PORT = dig[0];
		_delay_ms(DISPLAY_DELAY);
		DIG_PORT = 0x0F & (~(1 << Digit2));
		SEG_PORT = dig[1];
		_delay_ms(DISPLAY_DELAY);
		DIG_PORT = 0x0F & (~(1 << Digit3));
		SEG_PORT = dig[2];
		_delay_ms(DISPLAY_DELAY);
		DIG_PORT = 0x0F & (~(1 << Digit4));
		SEG_PORT = dig[3];
		_delay_ms(DISPLAY_DELAY);
и подключите нормально разряды индикатора, а то у вас в протеусе один разряд туда другой сюда.
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Dimon456, Вот тут я вообще задумался, на 8 МГц он вообще ничего не выводит, ну как так то, работают только разряды меняются, а вывода нету, не ошибка а просто ничего, на 1 МГц есть, странно (( А ну разряды индикатора, это так получилось просто, чтобы в протеусе совпадало, но тут дело не в индикации, а то что он толи зависает, толи останавливает цикл, может что с таймером не так?

Самсусамыч, Ну на ЖК надо симпатичный корпус, а семисегментники можно и на плате просто, креативный дизайн так сказать, но это как говорится на любителя, но для работы пойдет ))
СпойлерИзображение
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Я ваш код в реальном железе не проверял, только протеус.
Triple_H писал(а):на 1 МГц есть, странно
МК то же на 8МГц перевели или только студию?
Вот так код переделайте
Спойлерmain.c

Код: Выделить всё

// Triple_H 27.05.2020
// Индикатор с общим катодом
// Датчик на PD5


#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <string.h>
//===================
#include "dht11.h"

//===================
#define	DIG_PORT 							PORTC
#define	DIG_DDR  							DDRC
#define	SEG_PORT 							PORTB
#define	SEG_DDR  							DDRB
#define	Digit1  							PC0
#define	Digit2  							PC1
#define	Digit3  							PC2
#define	Digit4  							PC3
//#define DISPLAY_DELAY						0.2
#define SYMBOL_POINT						0b10000000
#define SYMBOL_MINUS						0b01000000
//===================
uint16_t 	ms = 0;
uint8_t 	sec = 0, min = 0, hour = 0;
uint32_t 	second_count = 0;
uint8_t 	refresh = 0;
uint8_t 	dig[4] = {0, 0, 0, 0};
uint8_t		DHT11_Temperature = DHT11_ERROR;
uint8_t		DHT11_Humidity = DHT11_ERROR;
uint32_t 	DHT11_Update_Time = 0;
//===================
// Массив для декодирования цифры в код числа для 7-сегментного индикатора
uint8_t digits[10] = {
	//hgfedcba
	0b00111111,
	0b00000110,
	0b01011011,
	0b01001111,
	0b01100110,
	0b01101101,
	0b01111101,
	0b00000111,
	0b01111111,
	0b01101111,
};



//===================
ISR(TIMER2_COMP_vect) 
{ static unsigned char segment;
	ms++;
	if(ms == 1000)
	{
		second_count++;
		ms = 0;
		sec++;
		if (sec == 60)
		{
			sec = 0;
			min++;
			if (min == 60)
			{
				min = 0;
				hour++;
				if (hour == 24)
				hour = 0;
			}
		}
	}
	
	// частота развертки при F_CPU 8000000UL получается 83Гц
	if(segment == 0) { SEG_PORT = 0x00; DIG_PORT = 0x0F& (~(1 << Digit1)); SEG_PORT = dig[0]; }
	if(segment == 3) { SEG_PORT = 0x00; DIG_PORT = 0x0F& (~(1 << Digit2)); SEG_PORT = dig[1]; }
	if(segment == 6) { SEG_PORT = 0x00; DIG_PORT = 0x0F& (~(1 << Digit3)); SEG_PORT = dig[2]; }
	if(segment == 9) { SEG_PORT = 0x00; DIG_PORT = 0x0F& (~(1 << Digit4)); SEG_PORT = dig[3]; }
	if(segment++ == 11) segment = 0;
	
}
//===================
void DHT11_Update(void)
{
	DHT11_Read(&DHT11_Temperature, &DHT11_Humidity);
	DHT11_Update_Time = second_count + DHT11_REFRESH_TIME;
	refresh = 1;
}

//===================
int main (void)
{
	// Запрещаем прерывания
	cli();
	// Настраиваем порты ввода-вывода
	SEG_DDR = 0xFF;
	SEG_PORT = 0x00;
	DIG_DDR = (1 << Digit1)|(1 << Digit2)|(1 << Digit3)|(1 << Digit4);
	DIG_PORT &= ~((1 << Digit1)|(1 << Digit2)|(1 << Digit3)|(1 << Digit4));
	// Настраиваем таймеры
	// Разрешение прерывания таймера 2
	TIMSK = (1 << OCIE2);
	// Настраиваем таймер 2 на подсчет секунд
	// Предделитель на 64
	TCCR2 = (1 << WGM21)|(0 << WGM20)|(1 << CS22)|(0 << CS21)|(0 << CS20);
	OCR2 = (F_CPU / 64 / 1000) - 1;	// ровно 1 ms
	// Обнуляем счетчик таймера 2
	TCNT2 = 0;
	// Запуск первого измерения влажности
	_delay_ms(100);
	DHT11_Update();
	// Разрешаем прерывания
	sei();
	// Основная программа
	while (1)
	{
		if(second_count >= DHT11_Update_Time)
		DHT11_Update();
		// Преобразование температуры в отдельные цифры для вывода
		if (refresh)
		{
			if (DHT11_Humidity!= DHT11_ERROR)
			{
				
		
			if (DHT11_Temperature!= DHT11_ERROR)
			{
				dig[0] = digits[DHT11_Temperature / 10];
				dig[1] = digits[DHT11_Temperature % 10];
				dig[2] = digits[DHT11_Humidity / 10];
				dig[3] = digits[DHT11_Humidity % 10];
			}
			else
			memset(dig, SYMBOL_MINUS, sizeof(dig));
			refresh = 0;
		}
		
			}		
	}
}
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Благодарю за помощь
Dimon456, Да и в железе так же, в протеусе хоть видно как меняются разряды, фьюзы менял на 1 МГц есть индикация, на 8 нету. Вот и странно, но я понял, что ему не нравится повторный опрос датчика, хотя опрос стандартный. По вашему варианту он не виснет, но и не опрашивает повторно, и опять же на 1 МГц.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Triple_H, значит вы что-то не правильно делаете в студии.
Давайте проверим, защейте вот этот hex. Фьюзы выставить на 8МГц.
main.zip
(1.27 КБ) 163 скачивания
На 1Мгц МК виснет в процедуре опроса датчика.
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Dimon456, Спасибо тебе, мил человек ))
Почти заработало, в железе правда не очень, показывает ересь какую то, но это наверное из-за того что у меня n-p-n транзисторы ))
Если не секрет и не там уж совсем все плохо было, в чем мой косяк?

з. ы. И не сочтите за совсем уж наглость, а можно или исходники вашей прошивки или под индикатор с общим катодом и n-p-n транзистор, а то у меня все восьмерки показывает )) Хотя что то меняется когда руку подносишь к нему, один разряд в основном ))
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Исходник выше выкладывал.
А про n-p-n транзисторы, то надо было в протеусе и рисовать эти транзисторы.
Схему свою выложите, подкорректирую исходник.
Triple_H писал(а):Если не секрет и не там уж совсем все плохо было, в чем мой косяк?
Думаю где-то в студии косяк.
Открыл глаза
Сообщения: 45
Зарегистрирован: Ср апр 23, 2014 22:17:24

Сообщение Triple_H »

Ну вот как то так у меня и в железе показывает, восьмерки, хотя иногда и девятка, интересно это нормально? Только транзисторы у меня кт315, чет их нету в протеусе ))
Если не сложно, то можно прошивку, буду благодарен. Я понял, буду копать тогда в студио что там не так то.
СпойлерИзображение
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Это hex пробуйте
main2.zip
(1.27 КБ) 188 скачиваний
Вот исходник
Спойлер

Код: Выделить всё

// Triple_H 27.05.2020
// Индикатор с общим катодом
// Датчик на PD5


#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <string.h>
//===================
#include "dht11.h"

//===================
#define	DIG_PORT 							PORTC
#define	DIG_DDR  							DDRC
#define	SEG_PORT 							PORTB
#define	SEG_DDR  							DDRB
#define	Digit1  							PC0
#define	Digit2  							PC1
#define	Digit3  							PC2
#define	Digit4  							PC3
//#define DISPLAY_DELAY						0.2
#define SYMBOL_POINT						0b10000000
#define SYMBOL_MINUS						0b01000000
//===================
uint16_t 	ms = 0;
uint8_t 	sec = 0, min = 0, hour = 0;
uint32_t 	second_count = 0;
uint8_t 	refresh = 0;
uint8_t 	dig[4] = {0, 0, 0, 0};
uint8_t		DHT11_Temperature = DHT11_ERROR;
uint8_t		DHT11_Humidity = DHT11_ERROR;
uint32_t 	DHT11_Update_Time = 0;
//===================
// Массив для декодирования цифры в код числа для 7-сегментного индикатора
uint8_t digits[10] = {
	//hgfedcba
	0b00111111,
	0b00000110,
	0b01011011,
	0b01001111,
	0b01100110,
	0b01101101,
	0b01111101,
	0b00000111,
	0b01111111,
	0b01101111,
};



//===================
ISR(TIMER2_COMP_vect) 
{ static unsigned char segment;
	ms++;
	if(ms == 1000)
	{
		second_count++;
		ms = 0;
		sec++;
		if (sec == 60)
		{
			sec = 0;
			min++;
			if (min == 60)
			{
				min = 0;
				hour++;
				if (hour == 24)
				hour = 0;
			}
		}
	}
	
	// частота развертки при F_CPU 8000000UL получается 83Гц
	if(segment == 0) { SEG_PORT = 0x00; DIG_PORT = 0x0F& ((1 << Digit1)); SEG_PORT = dig[0]; }
	if(segment == 3) { SEG_PORT = 0x00; DIG_PORT = 0x0F& ((1 << Digit2)); SEG_PORT = dig[1]; }
	if(segment == 6) { SEG_PORT = 0x00; DIG_PORT = 0x0F& ((1 << Digit3)); SEG_PORT = dig[2]; }
	if(segment == 9) { SEG_PORT = 0x00; DIG_PORT = 0x0F& ((1 << Digit4)); SEG_PORT = dig[3]; }
	if(segment++ == 11) segment = 0;
	
}
//===================
void DHT11_Update(void)
{
	DHT11_Read(&DHT11_Temperature, &DHT11_Humidity);
	DHT11_Update_Time = second_count + DHT11_REFRESH_TIME;
	refresh = 1;
}

//===================
int main (void)
{
	// Запрещаем прерывания
	cli();
	// Настраиваем порты ввода-вывода
	SEG_DDR = 0xFF;
	SEG_PORT = 0x00;
	DIG_DDR = (1 << Digit1)|(1 << Digit2)|(1 << Digit3)|(1 << Digit4);
	DIG_PORT &= ~((1 << Digit1)|(1 << Digit2)|(1 << Digit3)|(1 << Digit4));
	// Настраиваем таймеры
	// Разрешение прерывания таймера 2
	TIMSK = (1 << OCIE2);
	// Настраиваем таймер 2 на подсчет секунд
	// Предделитель на 64
	TCCR2 = (1 << WGM21)|(0 << WGM20)|(1 << CS22)|(0 << CS21)|(0 << CS20);
	OCR2 = (F_CPU / 64 / 1000) - 1;	// ровно 1 ms
	// Обнуляем счетчик таймера 2
	TCNT2 = 0;
	// Запуск первого измерения влажности
	_delay_ms(100);
	DHT11_Update();
	// Разрешаем прерывания
	sei();
	// Основная программа
	while (1)
	{
		if(second_count >= DHT11_Update_Time)
		DHT11_Update();
		// Преобразование температуры в отдельные цифры для вывода
		if (refresh)
		{
			if (DHT11_Humidity!= DHT11_ERROR)
			{
				
		
			if (DHT11_Temperature!= DHT11_ERROR)
			{
				dig[0] = digits[DHT11_Temperature / 10];
				dig[1] = digits[DHT11_Temperature % 10];
				dig[2] = digits[DHT11_Humidity / 10];
				dig[3] = digits[DHT11_Humidity % 10];
			}
			else
			memset(dig, SYMBOL_MINUS, sizeof(dig));
			refresh = 0;
		}
		
			}		
	}
}
Ответить

Вернуться в «AVR»