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

[Atmega16][ds18b20] - nie czyta poprawnie ID i temperatury

pustelnik933 03 Paź 2012 19:19 1842 3
  • #1 03 Paź 2012 19:19
    pustelnik933
    Poziom 9  

    Witam, próbuję odczytać temperaturę z mojego czujnika jednak wynosi ona ciągle -0.1, a gdy próbuje pobrać odczytać ID wyświetla mi puste miejsca lub krzaczki.
    Przy próbie podłączania za pierwszym razem niestety źle spojrzałem na schemat i odwrotnie podłączyłem zasilanie więc teraz nie wiem czy to wina kodu czy może jednak układu. Chociaż jakby coś z nim by było to raczej by nie odpowiadał na wywołania. Nie mniej kod podaje poniżej(robiony według poleceń w opracowaniu Cezary Klimasz teremometr ds18b20):

    Code:

    [syntax=c]
    /*************************************************************************
    Title:    testing output to a HD44780 based LCD display.
    Author:   Peter Fleury  <pfleury@gmx.ch>  http://jump.to/fleury
    File:     $Id: test_lcd.c,v 1.6 2004/12/10 13:53:59 peter Exp $
    Software: AVR-GCC 3.3
    Hardware: HD44780 compatible LCD text display
              ATS90S8515/ATmega if memory-mapped LCD interface is used
              any AVR with 7 free I/O pins if 4-bit IO port mode is used
    **************************************************************************/
    #include <stdlib.h>
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include "lcd.h"
    #include <util/delay.h>

    //makra
    #define WE 7
    #define PORT_1Wire PINC
    #define SET_1Wire DDRC&= ~_BV(WE)
    #define CLEAR_1Wire DDRC|= _BV(WE)

    /*
    ** constant definitions
    */



    /*
    ** function prototypes
    */


    char buf[8]; // zmienna do konwersji temperatury

    unsigned char RESET_PULSE(void)
    {
       unsigned char PRESENCE;
       CLEAR_1Wire;   
       _delay_us(500); //delayus(500);   
       SET_1Wire;
       _delay_us(30); //delayus(30);
       if(bit_is_clear(PORT_1Wire,WE))
       {
          PRESENCE = 1;
       }
       else
       {
          PRESENCE = 0;
       }
       _delay_us(470); //delayus(470);
       if(bit_is_set(PORT_1Wire,WE))
       {
       PRESENCE = 1;
       }
       else
       {
       PRESENCE = 0;   
       }
       return PRESENCE;
    }

    void send(char bit)
    {
       CLEAR_1Wire;
       _delay_us(5); //delayus(5);
       if(bit == 1)




       {
          SET_1Wire;
       }
       else
       {
          _delay_us(80); //delayus(80);
          SET_1Wire;
       }
    }

    unsigned char read(void)
    {
       unsigned char PRESENCE = 0;
       CLEAR_1Wire;
       _delay_us(2); //delayus(2);
       SET_1Wire;
       _delay_us(15); //delayus(15);
       if(bit_is_set(PORT_1Wire,WE))
       {
          PRESENCE = 1;
       }
       else
       {
          PRESENCE = 0;
       }
       return PRESENCE;
    }

    void send_byte(char wartosc)
    {
       unsigned char i;
       unsigned char pom;
       for(i = 0; i < 8; i++)
       {
          pom = wartosc>>i;
          pom &= 0x01;
          send(pom);
       }
       _delay_us(100);
    }

    unsigned char read_byte(void)
    {
       unsigned char i;
       unsigned char wartosc = 0;
       for(i = 0; i < 8; i++)
       {
          if(read())
          {
          wartosc|= 0x01<<i;
          _delay_us(15); //delayus(15);
          }
       }
       return(wartosc);
    }
    int main(void)
    {
        //char buffer[7];
       char temp1=0, temp2=0;
        //int  num=0;
        unsigned char sprawdz;
       
       
       // DDRD &=~ (1 << PD2);        /* Pin PD2 input              */
       // PORTD |= (1 << PD2);        /* Pin PD2 pull-up enabled    */


        /* initialize display, cursor off */
        lcd_init(LCD_DISP_ON);

       
        for (;;) {                           /* loop forever */
            /*
             * Test 1:  write text to display
             */
           
            /* clear display and home cursor */
            lcd_clrscr();
           
            /* put string to display (line 1) with linefeed */
            //lcd_puts("Termometr\nT: ");
          send_byte(0xCC);
          send_byte(0x33);
          lcd_puts((char)read_byte());
          lcd_puts(read_byte());
            /* cursor is now on second line, write second line */
            //lcd_puts(buffer);
           
            /* move cursor to position 8 on line 2 */
            lcd_gotoxy(0,1); 
           
            /* write single char to display */
            //lcd_putc(':');
            sprawdz=RESET_PULSE();
             if(sprawdz == 1)
             {
                send_byte(0xCC);
                send_byte(0x44);
                _delay_ms(30); //delayms(750);
                
                sprawdz=RESET_PULSE();
                send_byte(0xCC);
                send_byte(0xBE);
                
                temp1 = read_byte();
                temp2 = read_byte();
                
                sprawdz = RESET_PULSE();
                
                float temp=0;
                temp=(float)(temp1+(temp2*256))/16;
                
                dtostrf(temp,1,1,buf);
                lcd_puts(buf);
                _delay_ms(200); //delayms(200);
                
             }
             else
             {
                lcd_puts("Brak danych");
             }
          
           // itoa( num , buffer, 10);
                 
        }
    }

    [/syntax]


    Potrzebowałbym również jakiejś prostej biblioteki do kilku czujników zasilanych z zewnętrznego źródła i bez sprzętowego UART`a. Proszę o pomoc:)

    0 3
  • #3 04 Paź 2012 15:13
    pustelnik933
    Poziom 9  

    Mimo to wydaje mi się że ID powinno dobrze czytać a tak nie jest. A może mam zastosować inną bibliotekę z przerwaniami albo dodać timer?

    0
  • #4 21 Sty 2013 15:13
    pustelnik933
    Poziom 9  

    Zna ktoś może jakąś bibliotekę do obsługi 1-wire? bo próbuję teraz ponownie jednak co bym nie zrobił to ds18b20 ciągle mi wyczytuje że jest nawet jak go tam nie ma.

    0