logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Pytanie dotyczące DS18B20

Paweł Frąckowiak 17 Sty 2011 11:27 2977 13
REKLAMA
  • #1 9017785
    Paweł Frąckowiak
    Poziom 11  
    Witam serdecznie!!!

    Po dziwnych przygodach z LM35 postanowiłem przesiąść się na DS18B20 i niestety również coś nie działa jak trzeba. Podłączyłem DSa jak na rysunku poniżej:
    Pytanie dotyczące DS18B20

    z tą różnicą że ja mam zasilanie 3,3V

    Jak podłączyłem zasilanie to mój DS zaczął się grzać jak szalony, a LCD zgasł więc czym prędzej odłączyłem zasilanie.

    Napiszcie proszę po czym poznać, że ten układ jest zepsuty.

    Tak dla informacji pomierzyłem rezystancje pomiędzy wyprowadzeniami DSa i wygląda to tak:
    VCC - linia danych -> 670 ohm
    VCC - GND -> 710 ohm
    GND - linia danych -> nieskończoność

    Posiadam dwa takie DSy i na obu te wartości wyglądają tak samo.

    Czy te wartości mogą świadczyć o awarii moich termometrów?

    Pozdrawiam!!!
  • REKLAMA
  • #2 9017892
    sp3ots
    Poziom 38  
    Witam !
    Schemat poprawny ( ściągnięty z sieci ).
    Pokaż swój układ ( zdjęcie ).
    Dołącz też kod. ( jak w Bascomie, mogę sprawdzić )
    Pozdrawiam. Stefan
  • #3 9017908
    walek33
    Poziom 29  
    A przez przypadek nie pomyliłeś nóżek DS-a?
  • REKLAMA
  • #4 9018105
    piotrva
    VIP Zasłużony dla elektroda
    mnie to wygląda na pomylenie nóżek DS'a...
    i omomierzem tu nic nie zdziałasz, co najwyżej też możesz uszkodzić układ
    sprawdź po prostu nóżki DS'a z notą katalogową
  • #5 9021867
    Paweł Frąckowiak
    Poziom 11  
    Poniżej zamieszczam foto mojego podłączenia DS18B20:
    Pytanie dotyczące DS18B20
    żeby nie było wątpliwość środkowa nóżka wędruje do uC :-)

    Poniżej zamieszczam też kod bo i może w nim jest coś nie tak, ale osobiście uważam, ze coś nie tak ze sprzętem, ale oczywiście mogę się mylić.

    Kod:
    
    unsigned char reset_magistrali()
    {
    	unsigned char presence;
    	DDRC |= _BV(PC0);
    	_delay_us(500);
    	DDRC &= ~_BV(PC0);
    	_delay_us(30);
    	if ( bit_is_clear(PINC, PC0) )
    	{
    		presence = 1;
    	}
    	else
    	{
    		presence = 0;
    	}
    	
    	_delay_us(470);
    	
    	if ( bit_is_set(PINC, PC0) )
    	{
    		presence = 1;
    	}
    	else
    	{
    		presence = 0;
    	}
    	
    	return presence;
    }
    
    
    void wyslij_bit(char bit)
    {
    	DDRC |= _BV(PC0);
    	_delay_us(5);
    	
    	if (bit == 1)
    	{
    		DDRC &= ~_BV(PC0);
    		_delay_ms(80);
    		DDRC &= ~_BV(PC0);
    	}
    	
    }
    
    unsigned char odbierz_bit()
    {
    	unsigned char presence;
    	DDRC |= _BV(PC0);
    	_delay_us(2);
    	DDRC &= ~_BV(PC0);
    	_delay_us(15);
    	
    	if ( bit_is_set(PIND, PC0) )
    	{
    		presence = 1;
    	}
    	else
    	{
    		presence = 0;
    	}
    	
    	return presence;
    }
    
    void wyslij_bajt(char bajt)
    {
    	unsigned char zmienna;
    	
    	for ( unsigned char i = 0 ; i < 8 ; i++ )
    	{
    		zmienna = bajt >> i;
    		zmienna &= 0x01;
    		wyslij_bit(zmienna);
    		_delay_us(100);
    	}
    }
    
    unsigned char odbierz_bajt()
    {
    	unsigned char wartosc = 0;
    	
    	for ( unsigned char i = 0 ; i < 0 ; i++ )
    	{
    		if ( odbierz_bit() )
    		{
    			wartosc |= 0x01 << i;
    		}
    		_delay_us(15);
    	}
    	return wartosc;
    }
    
    float pomiar_temp()
    {
    	unsigned char test;
    	char temp_lsb, temp_msb;
    	float temp;
    	
    	test = reset_magistrali();
    	
    	if ( test == 1 )
    	{
    		wyslij_bajt(0xcc);
    		wyslij_bajt(0x44);
    		_delay_us(750);
    		test = reset_magistrali();
    		wyslij_bajt(0xcc);
    		wyslij_bajt(0xbe);
    		temp_lsb = odbierz_bajt();
    		temp_msb = odbierz_bajt();
    		
    		test = reset_magistrali();
    		
    		temp = (float)( temp_lsb + (temp_msb * 256) ) / 16;
    	}
    	else
    	{
    		temp = 1000;
    	}
    	return temp;
    }
    


    Z góry dzięki za uwagi
  • REKLAMA
  • #6 9021897
    Wojtek75
    Poziom 24  
    Czujnik jest źle podłączony. Link
  • #7 9021901
    sp3ots
    Poziom 38  
    Pomyliłeś zasilanie, odwrotnie, popatrz na schemat i porównaj z płytką.
  • REKLAMA
  • #8 9021906
    Paweł Frąckowiak
    Poziom 11  
    no widze linka który podesłałeś i sądzę mam dobrze podłączony czujnik. Patrząc od wypukłej strony czujnika GND jest pierwsze od lewej jak w linku który podesłałeś w środku jest linia danych a po prawej jest VCC i ja tak mam podłączone. To jest źle? Pytam bo może czegoś nie rozumiem...
  • #9 9021919
    sp3ots
    Poziom 38  
    Spójrz na czujnik od strony napisu, tak jak masz na schemacie i w linku.
  • #10 9021923
    piotrva
    VIP Zasłużony dla elektroda
    czytaj, pod tym pisze jak byk BOTTOM VIEW
    czyli widok od dołu.
    patrz na to co masz na górze, trzymasz ds'a tak, żebyś napisy (płaską część) miał do twarzy i patrzysz na ten rysunek na górze...
    ds pewnie spalony już, skoro się zagotował...
  • #11 9021943
    Paweł Frąckowiak
    Poziom 11  
    dobra przyznaje spaprałem...
    Zwracam honor i przepraszam, że się tak upierałem.
    Nie spojrzałem na napis, że to widok od dołu.

    Raz jeszcze dzięki!!!
  • #12 9063004
    Paweł Frąckowiak
    Poziom 11  
    witam
    chciałbym trochę odświeżyć temat, mam już nowe termometry, ale na wyświetlaczu po podłączeniu poprawny już teraz nic się nie wyświetla - to znaczy wyświetla się info o braku komunikacji z DSem. Poprawiłem plik makefile bo w nim nie zmieniłem taktowania uC w nadziej, że to przez to źle realizowana jest funkcja _delay_us(), ale niestety to nie pomogło. Mógłby ktoś rzucić okiem na kod powyżej i podrzucić pomysł co może być nie tak?

    Z góry dzięki!!!
  • #13 9105152
    Radkoo
    Poziom 12  
    DDRC - to jedynie ustawianie portu jako wejście lub wyjście tymczasem musisz ustawić jakąś na porcie (1 lub zero lub stan hi-Z) Ty tego nie robisz.
    Moja rada: porównaj jak to robią inni.

    Dołączam plik z przykładową implementacją poszczególnych funkcji w C. Bardzo ważną sprawą w tym protokole jest timing.

    Pozdrawiam

    p.s. po krótkim zastanowieniu ustawianie jedynie portów jako wyjścia lub wejścia będzie miało taki sam efekt jak ustawianie wartości PORT-ów. Drugi sposób wydaje mi się jednak bardziej czytelny i przejrzysty .

    Tak czy owak mam nadzieję że załączony dokument komuś się przyda
  • #14 9182359
    Paweł Frąckowiak
    Poziom 11  
    Od dłuższego czasu staram się coś mądrego wykombinować, ale mi nie bardzo wychodzi. Ciągle na LCD wyświetla mi zero stopni co nie jest oczywiście zgodne z prawdą :-(

    Poniżej zamieszczam kod, jeśli ktoś byłby w stanie mi podpowiedzieć gdzie robię błąd to byłbym zobowiązany.

    
    
    #define THERM_PORT			PORTC
    #define THERM_DDR			DDRC
    #define THERM_PIN			PINC
    #define THERM_DQ			PC0
    
    #define THERM_INPUT_MODE()	THERM_DDR &= ~(1<<THERM_DQ)
    #define THERM_OUTPUT_MODE()	THERM_DDR |= (1<<THERM_DQ)
    #define THERM_LOW()			THERM_PORT &= ~(1<<THERM_DQ)
    #define THERM_HIGH()		        THERM_PORT |= (1<<THERM_DQ)
    
    unsigned char reset_magistrali()
    {
    	unsigned char presence;
    	
    	THERM_OUTPUT_MODE();	
    	
    	THERM_LOW();			
    		
    	_delay_us(480);
    	
    	THERM_INPUT_MODE();		
     
    	_delay_us(60);	
    	
    	if ( bit_is_clear(THERM_PIN, THERM_DQ) )
    	{
    		presence = 1;
    	}
    	else
    	{
    		presence = 0;
    	}
    	
    	_delay_us(420);
    	
    	return presence;
    }
    
    
    void wyslij_bit(char bit)
    {
    	THERM_OUTPUT_MODE();
    
    	THERM_LOW();		
    	
    	_delay_us(1);
    	
    	if (bit == 1)
    	{
    		THERM_INPUT_MODE();
    	}
    
    	_delay_us(60);
    	THERM_INPUT_MODE();
    	
    }
    
    unsigned char odbierz_bit()
    {
    	unsigned char presence;
    	
    	THERM_OUTPUT_MODE();	
    	
    	THERM_LOW();			
    		
    	_delay_us(5);
    	
    	THERM_INPUT_MODE();	
    	
    	_delay_us(15);
    	
    	if ( bit_is_set(THERM_PIN, THERM_DQ) )
    	{
    		presence = 1;
    	}
    	else
    	{
    		presence = 0;
    	}
    	
    	_delay_us(45);
    	
    	return presence;
    }
    
    
    void wyslij_bajt(unsigned char bajt)
    {
    	unsigned char bit2send;
    	
    	for ( unsigned char i = 0 ; i < 8 ; i++ )
    	{
    		bit2send = bajt >> i;
    		bit2send &= 0x01;
    		wyslij_bit(bit2send);
    		
    		_delay_us(100);
    	}
    }
    
    unsigned char odbierz_bajt()
    {
    	unsigned char wartosc = 0;
    	
    	for ( unsigned char i = 0 ; i < 8 ; i++ )
    	{
    		if ( odbierz_bit() )
    		{
    			wartosc |= 0x01 << i;
    		}
    		
    		_delay_us(15);
    	}
    	return wartosc;
    }
    
    short int pomiar_temp()
    {
    	unsigned char test;
    	signed char temp_lsb, temp_msb;
    	short int temp;
    	
    	test = reset_magistrali();
    	
    	if ( test == 1 )
    	{
    		wyslij_bajt(0xcc);
    		wyslij_bajt(0x44);
    		_delay_us(750);
    		reset_magistrali();
    		wyslij_bajt(0xcc);
    		wyslij_bajt(0xbe);
    		temp_lsb = odbierz_bajt();
    		temp_msb = odbierz_bajt();
    		
    		test = reset_magistrali();
    		
    		temp = (short int)( temp_lsb + (temp_msb * 256) ) / 16;
    	}
    	else
    	{
    		temp = 1000;
    	}
    	return temp;
    }
    
    


    Z góry dzięki!!!
REKLAMA