Возникла проблема, помогите кто может ))
Собираю термометр-гигрометр на 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];
}
}
}
- Вложения
-
- Test-gig 8.rar
- Проект в AVRStudio
- (69.93 КБ) 213 скачиваний


