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

Termometr DS18B20 na ATmega8 - brak odczytu temperatury na wyświetlaczu HD44780

danloop 09 Sty 2011 17:08 3389 4
REKLAMA
  • #1 8982370
    danloop
    Poziom 15  
    Posty: 201
    Ocena: 11
    witam, po raz kolejny powtarzam temat, nie znalzałem rozwiązania wertujac inne dlatego piszę.
    Złożyłem termometr wg kursu AVR GCC. I nie działa naturalnie tzn. na wyświetlaczu pokazuje się jedynie napis Termometr a kiedy odłącze czujnik pojawia się wartość temperatury czasem 0.0C a czaem 800C. Na czujnik nie reaguje.
    Wyświetlaz obsługuje hd44780 i działa poprawnie sprawdzone na innych przykładach.

    Procesor zaprogramowany powodzeniem przez Avrdude (programator usbasp)

    będę wdzięczny za wskazówki
    main
    #include <stdio.h>
    #include <avr/io.h>
    #include <util/delay.h>
    #include "hd44780.h"
    #include "ds18b20.h"
    
    /* W tablicy będą formowane komunikaty tekstowe
       wysyłane do wyświetlacza */
    char str[17]="   Termometr    ";
    
    int main(void)
    {
          
      double temp;
    
      unsigned char ds18b20_pad[9];
      
      lcd_init();
      
      LCD_DISPLAY(LCDDISPLAY);  
     
      LCD_CLEAR;            
      
      
      LCD_LOCATE(0,0);
      lcd_puts(str);
    
      while(1)
      {
        
         if(ds18b20_ConvertT())
        {
           /* 750ms - czas konwersji */
           _delay_ms(750);
    
          
           ds18b20_Read(ds18b20_pad);
          
           temp = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;
          
           sprintf(str,"%4.1f\xdf""C", temp);
    
           LCD_LOCATE(5,1);
       
           lcd_puts(str);
        }
      }
    }


    ds18b20.h
    #ifndef DS18B20_H
    #define DS18B20_H
    
    /* DS18B20 przyłączony do portu  PD7 AVRa  */
    #define SET_ONEWIRE_PORT     PORTD  |=  _BV(7)
    #define CLR_ONEWIRE_PORT     PORTD  &= ~_BV(7)
    #define IS_SET_ONEWIRE_PIN   PIND   &   _BV(7)
    #define SET_OUT_ONEWIRE_DDR  DDRD   |=  _BV(7)
    #define SET_IN_ONEWIRE_DDR   DDRD   &= ~_BV(7)
    
    unsigned char ds18b20_ConvertT(void);
    int ds18b20_Read(unsigned char []);
    void OneWireStrong(char);
    unsigned char OneWireReset(void);
    void OneWireWriteByte(unsigned char);
    unsigned char OneWireReadByte(void);
    
    #endif
    

    ds18b20.c
    
    /*
       Plik ds18b20.c
       (minimum kodu do odczytu temperatury z ds18b20)
    
       xyz.isgreat.org
    */
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include "ds18b20.h"
    
    
    /**********************************************************/
    
    unsigned char ds18b20_ConvertT(void)
    {
      if (!OneWireReset()) return 0;
    
      OneWireWriteByte(0xcc); // SKIP ROM
      OneWireWriteByte(0x44); // CONVERT T
    
      return -1;
    }
    
    /***********************************************************/
    
    int ds18b20_Read(unsigned char scratchpad[])
    {
      unsigned char i;    
    
      if (!OneWireReset()) return 0;
    
      OneWireWriteByte(0xcc); // SKIP ROM
      OneWireWriteByte(0xbe); // READ SCRATCHPAD
    
      for(i=0; i<10; i++) scratchpad[i] = OneWireReadByte();
     
      return 1;
    }
    
    /**********************************************************/
    
    void OneWireStrong(char s)
    {
      if (s)
      {
         SET_ONEWIRE_PORT; 
         SET_OUT_ONEWIRE_DDR; 
      }
      else
      {
         SET_IN_ONEWIRE_DDR; 
      }
    }
    
    /**********************************************************/
    
    unsigned char OneWireReset()
    {
      CLR_ONEWIRE_PORT; 
    
      if (!(IS_SET_ONEWIRE_PIN)) return 0;  
    
      SET_OUT_ONEWIRE_DDR; 
      _delay_us(500);
      SET_IN_ONEWIRE_DDR; 
      _delay_us(70);
    
      if(!(IS_SET_ONEWIRE_PIN))
      {
        _delay_us(500);
        return(1);
      }
    
      _delay_us(500);
    
    return(0);
    }
    
    /**********************************************************/
    
    void OneWireWriteByte(unsigned char byte)
    {
       unsigned char i;
    
       CLR_ONEWIRE_PORT; 
    
       for (i=0; i<8; i++)
       {
         SET_OUT_ONEWIRE_DDR; 
    
         if (byte & 0x01)
         {
           _delay_us(7);
           SET_IN_ONEWIRE_DDR; 
           _delay_us(70);
         }
         else
         {
            _delay_us(70);
            SET_IN_ONEWIRE_DDR; 
            _delay_us(7);
         }
    
         byte >>= 1;
       }
    }
    
    /***********************************************************/
    
    unsigned char OneWireReadByte(void)
    {
      unsigned char i, byte = 0;
    
      SET_IN_ONEWIRE_DDR; 
      
      for (i=0; i<8; i++)
      {
         SET_OUT_ONEWIRE_DDR; 
         _delay_us(7);
         SET_IN_ONEWIRE_DDR; 
         _delay_us(7);
         byte >>= 1;
         
         if(IS_SET_ONEWIRE_PIN) byte |= 0x80;
    
         _delay_us(70);
      }
    
      return byte;
    }
    
  • REKLAMA
  • #2 8983396
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2203
    Zapewne nie zlinkowałeś programu z właściwą wersją printf - standardowa nie obsługuje float/double. Oprócz dodania biblioteki libptrintf trzeba też zdefiniować symbol linkera vsprintf. A najlepiej to całe double wywalić w diabły i przejść na int. Symbol F_CPU masz zdefiniowany?
  • REKLAMA
  • #3 8984053
    danloop
    Poziom 15  
    Posty: 201
    Ocena: 11
    tak F_CPU= 1 MHz, a mógłbyś trochę jaśniej co powinienem zrobić z tymi bibliotekami?
  • REKLAMA
  • #5 8984525
    danloop
    Poziom 15  
    Posty: 201
    Ocena: 11
    jesli chodzi o ustawienie float dla printf przy robieniu Makefile to ustwione.
    Rano z braku pomysłów odwróciłem czujnik i teraz mam:

    1 5V
    2 do procesora i do 5v przez rezystor
    3 do masy

    wczesniej miałem podłączone wg noty katalogowei i nie działało, nie rozumiem dlaczego
REKLAMA