Вот код:
dht_counter - счётчик, увеличиваемый по таймеру 1 раз в секунлду
#define MAX_TIMEOUT_DHT 6
#define EXT_DHT_DDR DDRD.3
#define EXT_DHT_OUT PORTD.3
#define EXT_DHT_IN PIND.3
unsigned char ext_dht_read()
{
unsigned char i, j;
unsigned char data[ 5 ];
dht_counter = 0;
//=============MCU send START
EXT_DHT_DDR = 1;
EXT_DHT_OUT = 1;
delay_ms( 500 );
EXT_DHT_DDR = 1;
EXT_DHT_OUT = 0;
delay_ms(20);
EXT_DHT_DDR = 0;
delay_us(40);
//=============check DHT response
if ( EXT_DHT_IN != 0 ) return 0;
while( EXT_DHT_IN == 0)
{
//может зависнуть - смотрим счётчик таймаута
if ( dht_counter >= MAX_TIMEOUT_DHT ) return 0;
}
delay_us(80);
while( EXT_DHT_IN != 0)
{
//может зависнуть - смотрим счётчик таймаута
if ( dht_counter >= MAX_TIMEOUT_DHT ) return 0;
}
//===============receive 40 data bits
for ( j = 0; j < 5; j++ )
{
data[ j ] = 0;
for( i = 0; i < 8; i++ ) {
while( EXT_DHT_IN == 0)
{
//может зависнуть - смотрим счётчик таймаута
if ( dht_counter >= MAX_TIMEOUT_DHT ) return 0;
}
delay_us (33);
if ( EXT_DHT_IN != 0 ) data[ j ] |= ( 1 << ( 7 - i ) );
while( EXT_DHT_IN != 0)
{
//может зависнуть - смотрим счётчик таймаута
if ( dht_counter >= MAX_TIMEOUT_DHT ) return 0;
}
}
}
if ( (unsigned char) ( data[ 0 ] + data[ 1 ] + data[ 2 ] + data[ 3 ] ) != data[ 4 ] ) return 0;
// если значения по указанным индексам = 0, то это ДХТ11
if ( data[ 1 ] == 0 && data[ 3 ] == 0 ) {
ext_tmpr = data[ 2 ] * 10;
ext_humm = data[ 0 ] * 10;
}
// если нет. то это ДХТ22
else {
ext_tmpr = ( data[ 2 ] & 0x7F ) * 256 + data[ 3 ];
ext_humm = ( data[ 0 ] * 256 ) + data[ 1 ];
if ( data[ 2 ] & 0x80 ) ext_tmpr *= -1;
}
// если получены все нули, значит ошибка чтения данных
if ( ext_tmpr == 0 && ext_humm == 0 ) return 0;
return 1;//checksum
}
Да, кстати, отключение прерываний на время считываний данных результатов не дало, при моделировании в протеусе- показывает всё сотка в сотку, но протеус штука такая, доверять особо нельзя.


