Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[mega32][C] Odczyt temperatury z kilku ds18b20

01 Gru 2010 18:28 2063 4
  • Poziom 11  
    Witam

    Mam problem z odczytaniem temperatury z 2-uch ds18b20 program napisałem w C w oparciu o znalezione pliki owire.c i owire.h program się kompiluje jednak na wyświetlacz nie trafiają informacje o MSB i LSB (na początku chcę przetestować na jednym ds18b20 bez konwersji na temperaturę) jedyną modyfikacją jaką wprowadziłem było zdefiniowanie typu u08 jako unsigned char gdyż AVR Studio krzyczało mi, że brak takiego typu... (prawdopodobnie tu jest błąd) niżej dodaję pliki:

    temperatura.c (MAIN)

    Code:

    #define F_CPU 16000000L    // 16 MHz - turn on external resonator (fuse bits)
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include "HD44780.h"
    #include "owire.h"

    char* odczyt_temperatury(u08 uklad){
    char* buf="";
    u08 sprawdz;
    u08 LSB = 0, MSB = 0;
    float temp = 0;
    sprawdz = owire_init();
          if(sprawdz==1)
          {
             owire_send_byte(0x55);      //SEND ROM
           owire_send_rom(uklad);
             owire_send_byte(0x44);      //CONVERT T
             owire_delay(3000);         //oczekiwanie - czas konwersji
             sprawdz = owire_init();//wysylanie sygnalu reset
             owire_send_byte(0x55);      //SEND ROM
           owire_send_rom(uklad);
             owire_send_byte(0xBE);      //READ SCRATCHPAD

             LSB = owire_get_byte();      //odczyta czesci mlodszej
             MSB = owire_get_byte();      //odczyta czesci starszej

             sprawdz = owire_init();//zwolnienie magistrali
             
             temp=(float)(LSB+(MSB*256))/16;
                     
             //dtostrf(temp,3,1,buf);   //konswersja FLOAT na STRING
           sprintf(buf,"M: %d L: %d",MSB,LSB);
       }
    return buf;
    }



    //-------------------------------------
    // main program
    //-------------------------------------
    int main(void)
    {
    owire_search_rom();
    LCD_Initialize();

    do{
           LCD_Clear();
           LCD_GoTo(0,0);
           LCD_WriteText("Test ds18b20");
           LCD_GoTo(0,1);
           LCD_WriteText(odczyt_temperatury(0));
          _delay_ms(200);

    }while(1);

    return 0;
    }
    //-------------------------------------
    // End of file
    //-------------------------------------


    owire.h
    Code:

    /**********************************************************************************
    Konfiguracja pinu DQ
    **********************************************************************************/
    #define DDR_DQ DDRC
    #define PORT_DQ PORTC
    #define PIN_DQ PINC
    #define DQ 0

    #define INITDQ PORT_DQ&=~(1<<DQ);
    #define DQOUT DDR_DQ|=(1<<DQ);
    #define DQIN DDR_DQ&=~(1<<DQ);

    typedef unsigned char u08;

    /****************************************************************************************************
    Ilość urządzeń 1wire
    ****************************************************************************************************/
    #define AMOUNT 1

    /****************************************************************************************************
    Definicje funkcji
    ****************************************************************************************************/
    u08 owire_init(void);
    void owire_delay(unsigned int);
    void owire_send_byte(u08);
    u08 owire_get_byte(void);
    void owire_send_rom(u08);
    void owire_search_rom(void);


    owire.c
    Code:

    #define F_CPU 16000000L
    #include <avr/io.h>
    #include <util/delay.h>
    #include "owire.h"

    /****************************************************************************************************
    Tablica kodów ROM
    ****************************************************************************************************/
    u08 rom[AMOUNT][8];

    /****************************************************************************************************
    Opóźnienie.
    ****************************************************************************************************/

    void owire_delay(unsigned int __count)
    {
       __asm__ volatile (
          "1: sbiw %0,1" "\n\t"
          "brne 1b"
          : "=w" (__count)
          : "0" (__count)
       );
    }

    /****************************************************************************************************
    Wysyła sygnał RESET i odbiera sygnał PRESENCE PULSE. Jeśli powodzenie zwraca 0.
    ****************************************************************************************************/
    u08 owire_init(void)
    {
       u08 ret;
       
       INITDQ
       DQOUT
       _delay_ms(0.6);   
       DQIN
       _delay_us(70);
       ret = (PIN_DQ&(1<<DQ));
       _delay_ms(0.6);
       
       return ret;
    }

    /****************************************************************************************************
    Wysyła pojedynczy bit na linię
    ****************************************************************************************************/
    void owire_send_bit(u08 data)
    {
       DQOUT
       _delay_us(10);
       if(data&0x01)
          DQIN
       _delay_us(70);
       DQIN
       _delay_us(10);
    }

    /****************************************************************************************************
    Odbiera pojedynczy bit z linii
    ****************************************************************************************************/
    u08 owire_get_bit(void)   
    {
       u08 data;

       DQOUT
       _delay_us(5);
       DQIN
       _delay_us(5);
       data=((PIN_DQ>>DQ)&0x01);

       _delay_us(80);
       return data;
    }

    /****************************************************************************************************
    Wysyła bajt danych na linię
    ****************************************************************************************************/
    void owire_send_byte(u08 data)
    {
       u08 licznik;
       
       for(licznik=0;licznik!=8;licznik++)
       {
          owire_send_bit((data>>licznik));
       }
       
       _delay_us(40);
    }

    /****************************************************************************************************
    Odbiera bajt danych z linii
    ****************************************************************************************************/
    u08 owire_get_byte(void)
    {
       u08 licznik, data=0;
       
       for(licznik=0;licznik!=8;licznik++)
       {
          data|=(owire_get_bit()<<licznik);
       }
       
       _delay_us(40);
       return data;
    }

    /****************************************************************************************************
    Wysyła 64-bitowy numer identyfikacyjny ROM z tablicy rom[AMOUNT][8] wybranego urządzenia.
    ****************************************************************************************************/
    void owire_send_rom(u08 numer)
    {
       u08 licznik;
       
       for(licznik=0;licznik!=8;licznik++)
       {
          owire_send_byte(rom[numer][licznik]);
       }
       
       _delay_us(40);
    }

    /****************************************************************************************************
    Zczytuje kody ROM wszystkich urządzeń na linii 1wire
    ****************************************************************************************************/
    void owire_search_rom(void)
    {
       u08  discrp = 0, last_bit = 0, dscnt = 0, last_zero, a, b, tmp;

       do
       {
       
          while(owire_init());
          owire_send_byte(0xf0);
         
          last_zero = 0;
          for(a = 0; a < 64; a++)
          {
         
             b = owire_get_bit();
             tmp = owire_get_bit();
             
             if((b == 0)&&(tmp == 0))
             {
                if(a == discrp)
                   b = 1;
                else if(a > discrp)
                   b = 0;
                else
                   b = last_bit;
                if(b == 0)
                   last_zero = a;
             }
             
             owire_send_bit(b);
             rom[dscnt][(a / 8)]|=(b << (a % 8));
             last_bit = b;
          }
         
          dscnt++;
          discrp = last_zero;
       } while((dscnt < AMOUNT)&&(discrp > 0));
       
    }


    pliki HD44780.h i HD44780.c z przykładów ze strony kamami.pl (te pliki działają)

    Jakby ktoś mógł sprawdzić co żem nabroił, że to nie działa :/

    Na wyświetlaczu pojawia się tylko napis "Test ds18b20" więc wyświetlacz jest ok :)

    Drugi problem już mniej ważny, mianowicie jak zdefiniować i wyświetlić znak stopnia.

    Pozdrawiam
    Rafał
  • Poziom 15  
    Ja na Twoim miejscu posprawdzałbym czasy opóźnień jakie masz poustawiane. Ja w swoim projekcie (m.in. 8 DS18B20 na jednej magistrali) miałem inne czasy opóźnień i wszystko działało. W tym może być problem braku odczytu z czujnika.
  • Poziom 39  
    gdL napisał:
    Użyj bibliotek, które napisałem... tu masz link do mojego bloga :
    ...

    A ja proponuję, byś napisał własny program, bo z tego co widzę, to nie bardzo rozumiesz jak wygląda procedura RESET.
    Funkcja
    Code:
    u08 owire_init(void) 

    zwraca zero, jak jakiś układ na magistrali odpowie i jeden, jeśli żaden układ nie odpowie na sygnał RESET.
    Twój kod reaguje odwrotnie niż powinien - pomyśl :D
  • Poziom 11  
    zumek napisał:
    gdL napisał:
    Użyj bibliotek, które napisałem... tu masz link do mojego bloga :
    ...

    A ja proponuję, byś napisał własny program, bo z tego co widzę, to nie bardzo rozumiesz jak wygląda procedura RESET.
    Funkcja
    Code:
    u08 owire_init(void) 

    zwraca zero, jak jakiś układ na magistrali odpowie i jeden, jeśli żaden układ nie odpowie na sygnał RESET.
    Twój kod reaguje odwrotnie niż powinien - pomyśl :D


    ale fail... faktycznie :F zanegowałem ten Reset i już działa :D teraz tylko problem bo mi miga ten tekst ale to już sobie wyreguluję opóźnieniami :F