Понадобилось мне добавить в устройство датчик влажности. Купил на али. Написал код. Но не работает. Несколько дней бился, но так и не смог добиться результата.
Имею вот такую программу
Спойлер
Код: Выделить всё
//////////////////////////////////////////////////////////
// ПАРАМЕТРЫ UART //
//////////////////////////////////////////////////////////
#define BAUD 9600UL // Скорость обмена по UART
#define SPEED ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//Порт, управляющий нагрузками
#define PIN_LOAD PINA
#define DDR_LOAD DDRA
#define PORT_LOAD PORTA
#define PIN_SENSOR PINC
#define DDR_SENSOR DDRC
#define PORT_SENSOR PORTC
#define PIN_DET1 PC0 //Считывание 1го положения выключателя
#define PIN_DET2 PC1 //Считывание 2го положения выключателя
#define PIN_PIR PC2 //Обработка датчика движения
#define PIN_DHT11 PC3 //Считывание значение влажности
#define PIN_LAMP PA0 //Управление включением лампой
#define PIN_VENT PA1 //Управление включением вентилятора
#define PIN_DEBUG1 PA2 //Пин для отладки
#define PIN_DEBUG2 PA3 //Пин для отладки
#define PUSH_SENS1 (1<<PIN_DET1) //нажата кнопка 1
#define PUSH_SENS2 (1<<PIN_DET2) //нажата кнопка 2
uint8_t temp;
uint8_t humi;
/*********************************************************
НАБОР ФУНКЦИЙ ДЛЯ РАБОТЫ ЧЕРЕЗ UART
*********************************************************/
void init_uart(void){
UCSRB = (1<<TXEN|1<<RXEN|0<<RXCIE); // Настройка UART
UCSRC = (1<<URSEL|1<<UCSZ1|1<<UCSZ0);
UBRRL = (uint8_t)(SPEED & 0xFF);
UBRRH = (uint8_t)(SPEED >> 8);
}
void out_uart(uint8_t data){ // Передача байта через UART
while(!(UCSRA&(1<<UDRE))); // Ожидание готовности UART к передаче
UDR = data; // Запись в регистр UDR байта данных начинает процесс передачи
}
uint8_t in_uart(void){ // Прием байта из UART
while(!(UCSRA&(1<<RXC))); // Ожидание прихода байта
return UDR; // Возвращение принятого байта
}
uint8_t dht11_read ()
{
uint8_t datadht[5]; // массив для значений датчика
datadht[0] = datadht[1] = datadht[2] = datadht[3] = datadht[4] = 0 ; //обнуляем массив
//Инициализация датчика
DDR_SENSOR |=(1<<PIN_DHT11); // выход
PORT_SENSOR &=~(1<<PIN_DHT11); //в низкий уровень
_delay_ms (18);
//Переводим порт в режим чтения
PORT_SENSOR |=(1<<PIN_DHT11); //отпускаем линию
_delay_us (40);
DDR_SENSOR &=~(1<<PIN_DHT11); // вход, режим чтения
//Ждем сигнал готовности датчика к передаче
while (PIN_SENSOR & (1<<PIN_DHT11)){} //ждем, датчик должен ответить 0
_delay_us (60);
while (!(PIN_SENSOR & (1<<PIN_DHT11))){} //Ждем отпускания линии датчиком
_delay_us (60);
//Начало приема данных
while (PIN_SENSOR & (1<<PIN_DHT11)){} //эжем начала передачи, начинается с нуля, примерно через 80 мс
for (uint8_t byte = 0; byte < 5; byte++)
{
datadht[byte]=0;
for (uint8_t bit=0; bit<8; bit++)
{
cli (); // запрещаем прерывания
while (!(PIN_SENSOR & (1<<PIN_DHT11))){} //ждем когда датчик отпустит шину
_delay_us (30); //задержка высокого уровня при 0 30 мкс
if ((PIN_SENSOR & (1<<PIN_DHT11))){ //если по истечению времени сигнал на линии высокий, значит передается 1
datadht[byte]|=1<<(7-bit); //тогда i-й бит устанавливаем 1
}
while (PIN_SENSOR & (1<<PIN_DHT11)); // ждем окончание 1
sei ();// разрешаем общее прерывание
}
}
humi = datadht[0];
return 0;
}
int main(void)
{
//===Инициализация портов====
//Порт на выход
DDR_LOAD |= (1<<PIN_LAMP|1<<PIN_VENT| 1<<PIN_DEBUG1|1<<PIN_DEBUG2);
PORT_LOAD &= ~(1<<PIN_LAMP|1<<PIN_VENT| 1<<PIN_DEBUG1|1<<PIN_DEBUG2); //обнуляем выход
//Вход с подтяжкой
DDR_SENSOR &= ~(1<<PIN_DET1|1<<PIN_DET2|1<<PIN_PIR|1<<PIN_DHT11);
PORT_SENSOR |= (1<<PIN_DET1|1<<PIN_DET2|1<<PIN_PIR|1<< PIN_DHT11);
_delay_ms(1000);
init_uart();
while(1)
{
dht11_read ();
_delay_ms(50);
out_uart(humi);
_delay_ms(50);
}
}
На УАРТ ничего не идет.
Вот что показывает логический анализатор, подключенный на ножку данных датчика
Только передний "провал" показывает длительностью 18ms. Потом все импульсы и паузы, либо длительностью 50, либо 100 us.
Причем, посылка делается один раз. Потом просто высокий уровень стоит.
Не пойму, то ли с программой что то, то ли датчик неисправный какой то пришел.
Может кто то сталкивался с таким?
Спасибо.