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

PIC16F84 i DS18B20 - brak odpowiedzi na reset 1-wire, co sprawdzić?

mikrorem 27 Wrz 2005 18:15 2073 8
REKLAMA
  • #1 1853862
    mikrorem
    Poziom 12  
    Posty: 30
    Pomógł: 2
    Ocena: 1
    Mam czujnik DS18B20 podłączonego do PIC16F84 pod nozke RA4 i do tego rezyztor podciagający 5kOhm (ma byc 4.7 ale).
    Nie moge nawet dokonac resetu to znaczy nie odpowiada DS. Jest dobry.
    Oto kod do resetu.

    char OW_Reset(void)
    {
    char result;

    TRISA |= 0x10; // Write '1' bit, i sterujemy RA4
    TRISA &= 0xEF; // Write '0' bit, i sterujemy RA4
    OW_pin=0;
    Dellay_us(250); // czekamy 250us
    Dellay_us(250);
    TRISA |= 0x10; // Write '1' bit, i sterujemy RA4
    Dellay_us(70);

    result = OW_pin; // Sample for presence pulse from slave

    Dellay_us(250);
    Dellay_us(250);

    return (result); // Return sample presence pulse result
    }

    i nic nie działa.
    Pomocy.
  • REKLAMA
  • #2 1853950
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    1. Czy ustawiłeś gdzieś stan portu na "1"?
    2. Generacja przebiegów przez modyfikacje rejestru TRISA w przypadku RA4 nie jest konieczna, ten pin posiada wyjście z otwartym drenem więc spokojnie można sterować rejestrem PORTA.
  • REKLAMA
  • #3 1854087
    mikrorem
    Poziom 12  
    Posty: 30
    Pomógł: 2
    Ocena: 1
    Tak ustawilem na 1.
    Z tego portu musze odczytywać stan bitu więc musze go ustawic TRISA na 1 ale aby wymusic stan niski musze zadac TRISA na 0 tego bitu.
    A moze ja o czyms nie wiem?

    Kombinuje narazie z ustawiniami czasów.
    Zobacze co to da.
    Czekam na inne pomysły lub przykłady.
  • #4 1854305
    tmg83
    Poziom 14  
    Posty: 68
    Pomógł: 5
    rozumiem, ze Dellay_us() to jakas funkcja, ktora sam napisales? Moze nie opoznia jak powinna. Moglbys kod pokazac? Podaj tez wartosc kwarcu
  • REKLAMA
  • #5 1854320
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    mikrorem napisał:
    Tak ustawilem na 1.
    TFU, miałem na myśli ZERO
    mikrorem napisał:
    Z tego portu musze odczytywać stan bitu więc musze go ustawic TRISA na 1 ale aby wymusic stan niski musze zadac TRISA na 0 tego bitu.
    Żeby odczytywać wystarczy TRIS RA4 ustawić na 0 i PORT RA4 ustawić na 1, bo ten port jest z otwartym drenem.
  • #6 1856122
    mikrorem
    Poziom 12  
    Posty: 30
    Pomógł: 2
    Ocena: 1
    Dzieki za radę bede się stosował.

    Co do braku komunikacja mam chyba cos z czasami.
    Oto moj kod:

    //**********************************************************************
    //procedura odczytywania z magistrali 1-wire (1 drut)
    //**********************************************************************
    void OW_Odczyt_T(void)
    {
      char n;
      if(OW_Reset())     //czy cos jest na linii (0-cos jest)
      {
        Send_string("Brak DS18B20");  
      }
      else
      {
        Send_string("Jest DS18B20");
        Send_int(temp);
        temp=0;
      }
      OWWriteByte(0xCC);  //skip ROM
      OWWriteByte(0x44);  //perform temperature conversion
      Dellay_x(6);
      
      if(OW_Reset())     //czy cos jest na linii (0-cos jest)
      {
        Send_string("Brak DS18B20");  
      }
      else
      {
      Send_string("Jest DS18B20 ");
        Send_int(temp);
        temp=0;
      }  
      OWWriteByte(0xCC);  //skip ROM
      OWWriteByte(0xBE);  //read the result  
      
      for(n=0;n<9;n++)
      {
        T[n]=OWReadByte();
      }
    }
    
    //-----------------------------------------------------------------------------
    // Write 1-Wire data byte
    //
    void OWWriteByte(char data)
    {
      char loop;
      for (loop=0; loop<8; loop++)  // Loop to write each bit in the byte, LS-bit first
      {
        if(data & 0x01)     //zapisujem 1
        {
          TRISA &= 0xEF;     //  0 
          OW_pin=0;
          Dellay_us(8); 
          TRISA |= 0x10;     //  1 
          Dellay_us(8);        
        }
        else                //zapisujemy 0
        {
          TRISA &= 0xEF;     //  0
          OW_pin=0;
          TRISA |= 0x10;     //  1 
          Dellay_us(15);       
        }
      data>>=1;                     // shift the data byte for the next bit
      }
    }
    
    //-----------------------------------------------------------------------------
    // Read 1-Wire data byte and return it
    //
    char OWReadByte(void)
    {
      char loop, result=0;
    	
      for (loop=0; loop<8; loop++)  // shift the result to get it ready for the next bit
      {
        TRISA &= 0xEF;     //  0 
        OW_pin=0;
        TRISA |= 0x10;     //  1
          Dellay_us(240);
          Dellay_us(240);
        if(OW_pin)           // czy 0 czy 1
        {
          result = (result >> 1) | 0x80;
        }
        else
        {
          result >>= 1;
        }
      Dellay_us(255);
      }
      return (result);
    }
    
    //-----------------------------------------------------------------------------
    // Generuje reset na 1-Wire i zwraca 0 jesli cos zglosilo gotowosc.
    //
    char OW_Reset(void)
    {
    char  result;
    
      TRISA |= 0x10;       // Write '1' bit, i sterujemy RA4
      TRISA &= 0xEF;       // Write '0' bit, i sterujemy RA4    
        OW_pin=0;
      Dellay_us(120);
        TRISA |= 0x10;    // Write '1' bit, i sterujemy RA4 
        Dellay_us(12);
           
        result = OW_pin;     // Sample for presence pulse from slave
    
      Dellay_us(100);     //???? czy potrzebne ????
        
      return (result);   // Return sample presence pulse result  
    }
    
    void Dellay_us(unsigned char czas)	//odmierza czas co 1us
    {
      for(;czas!=0;czas--)
        {;}
    }
    
    void Dellay_x(unsigned char czask)	/*odmierza czas co 0,05s*/
    {
      unsigned int czas1;
      for(;czask!=0;czask--)
        {
           for(czas1=5000;czas1!=0;czas1--)
             {;}
        }
    }
    
    
    


    Co wy na to?
  • #7 1857312
    tmg83
    Poziom 14  
    Posty: 68
    Pomógł: 5
    mikrorem napisał:

    void Dellay_us(unsigned char czas) //odmierza czas co 1us
    {
    for(;czas!=0;czas--)
    {;}

    }

    nie znam PICow, ale jestes pewien, ze dekrementacja, porownanie i skok zajmuja 1 us? jesli Twoj kompilator generuje pliki .asm to zeknij tam, odszukaj funkcje Dellay_us, znajdz petle, poszukaj w jakiejs dokumentacji do assemblera na PICe ile instrukcje wykonywane w petli zajmuja cykli maszynowych, sprawdz tez w jakiejs dokumentacji ile w PICu cykli zegarowych przypada na jeden cykl maszynowy, pomnoz to razy ilosc cykli maszynowych zajmowanych przez te instrukcje, ktore sprawdzales, podziel przez ilosc megahercow Twojego kwarcu i wynikiem bedzie ilosc mikrosekund jaka zajmuje jedna iteracja Twojej petli.
  • REKLAMA
  • #8 1857761
    mikrorem
    Poziom 12  
    Posty: 30
    Pomógł: 2
    Ocena: 1
    Prawda.
    Właśnie rozpoczynam analize tej funkcji.
  • #9 1896761
    mikrorem
    Poziom 12  
    Posty: 30
    Pomógł: 2
    Ocena: 1
    Dokladnie ta funkcja jest wykonywana w 5us wiedz drobne korekty w ustawieniach czasow i mam caly kod.
    Mam caly kod obslugi DS18B20 wlasnego autorstwa.
    Odczyt ROM, zapis rozdzielczosci, konwersja temperatury itp.

    Pozdrawiam.

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy problemu braku odpowiedzi czujnika DS18B20 podłączonego do mikrokontrolera PIC16F84 na magistrali 1-wire podczas próby resetu. Użytkownik stosuje pin RA4 z rezystorem podciągającym 5 kΩ (zamiast zalecanych 4,7 kΩ) i zgłasza, że czujnik nie odpowiada na sygnał resetu. Wskazano, że pin RA4 ma wyjście typu open-drain, więc sterowanie powinno odbywać się przez rejestr PORTA, a nie TRISA, który służy do konfiguracji kierunku portu. Konieczne jest ustawienie TRISA RA4 na wejście (1) do odczytu stanu, a PORTA RA4 na 1, aby wymusić stan wysoki. Problem może wynikać z nieprawidłowego generowania czasów w funkcji opóźniającej Dellay_us(), która powinna być dokładnie skalibrowana względem częstotliwości kwarcu. Zalecane jest sprawdzenie implementacji funkcji opóźniającej w asemblerze, uwzględniając liczbę cykli maszynowych i częstotliwość taktowania. Po korekcie czasów użytkownik potwierdził poprawne działanie całego kodu obsługi DS18B20, w tym odczytu ROM, ustawiania rozdzielczości i konwersji temperatury.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA