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.

code blocks zmienne zmiennoprzecinkowe

majki1995 30 Lip 2012 22:33 1741 10
  • #1 30 Lip 2012 22:33
    majki1995
    Poziom 10  

    Mam takie pytanie w jaki sposób można włączyć zmienne zmiennoprzecinkowe w code blocks ponieważ nie mogę nigdzie tego znaleźć za pomoc wielkie dzięki

    0 10
  • #3 31 Lip 2012 15:32
    majki1995
    Poziom 10  

    Nie bardzo rozumiem, w jaki sposób władcza się zmienne w notatniku?

    0
  • #5 31 Lip 2012 21:59
    majki1995
    Poziom 10  

    Sory literówka. Propozycja trochę spóźniona, właśnie podczas przerabiania pierwszego kursu z podanego linku napotkałem ten problem. Wszystkie poprzednie programy mi działały, ale gdy doszedłem do tego z czujnikiem ds18b20 pojawił się ten problem. Autor pisze, że trzeba włączyć zmienne zmiennopozycyjne i pokazuje jak to zrobię dla pakietu winavr, a nigdzie nie mogę w sieci tego znaleźć dla code blocks podczas kompilacji wyskakuje mi taki komunikat

    code blocks zmienne zmiennoprzecinkowe
    Wszystkie biblioteki są dodane, więc stwierdziłem, że to mogą być te zmienne.
    Jeżeli nie, to, co mogę robić źle, że mi to nie działa.
    Pozdrawiam

    0
  • #6 31 Lip 2012 22:13
    gaskoin
    Poziom 38  

    Tak, to bardzo znany bug kompilatora wynikający bezpośrednio ze źle zaprojektowanego krzemu. Zmień IDE a wszystkie problemy magicznie znikną!

    Pokaż kod, żebyśmy mogli Ci powiedzieć co masz źle.

    0
  • #7 31 Lip 2012 22:40
    LordBlick
    VIP Zasłużony dla elektroda

    Zgaduję - Dopisz na początku pliku main.c, jeśli tam tego nie ma :

    Kod: C
    Zaloguj się, aby zobaczyć kod

    Jeśli już tam to jest, oznacza to, że nie masz podanej prawidłowej ścieżki do avrlibc w opcjach kompilatora i ew. linkera.
    P.S. Rada na przyszłość przy zwracaniu się na forum o pomoc - dobrze opisz następujące punkty:
    1. Co chcesz osiągnąć i czego problem dotyczy,
    2. Co zrobiłeś z tym do tej pory i w jaki sposób,
    3. Dlaczego uważasz że masz z tym problem...
    W innym przypadku możesz się spotkać z niezrozumieniem użytkowników(jak na załączonym wyżej obrazku) i moderatorów.

    0
  • #8 01 Sie 2012 20:54
    majki1995
    Poziom 10  

    Kod razem z bibliotekami skopiowałem ze strony. Link

    Code:
    /*
    
       Plik "main.c"

       KURS AVR-GCC cz.5
       (xyz.isgreat.org)

       Termometr cyfrowy, przykład nr. 3
       (schemat i opis działania w artykule)
       atmega16 (1MHz)
    */

    #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)
    {
      /* Zmienna przechowuje aktualną wartość temperatury */       
      double temp;
      /* W tablicy zapisywane będą dane odczytane z układu ds18b20 */
      unsigned char ds18b20_pad[9];
     
      /* Funkcja inicjalizuje wyświetlacz */
      lcd_init();
      /* Włącza wyświetlanie */
      LCD_DISPLAY(LCDDISPLAY); 
      /* Czyści  ekran */
      LCD_CLEAR;           
     
      /* Wyświetla tytuł */ 
      LCD_LOCATE(0,0);
      lcd_puts(str);

      while(1)
      {
        /* Funkcja 'ds18b20_ConvertT' wysyła do układu ds18b20
           polecenie pomiaru */     
         if(ds18b20_ConvertT())
        {

           /* 750ms - czas konwersji */
           _delay_ms(750);

          /* Odczyt z układu ds18b20, dane zapisywane są w tablicy ds18b20_pad.
             Dwie pierwsze pozycje w tablicy to kolejno mniej znaczący bajt i bardziej
         znaczący bajt wartość zmierzonej temperatury */           
           ds18b20_Read(ds18b20_pad);
             
          /* Składa dwa bajty wyniku pomiaru w całość. Cztery pierwsze bity mniej
             znaczącego bajtu to część ułamkowa wartości temperatury, więc całość
             dzielona jest przez 16 */       
           temp = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;
         
          /* Formułuje komunikat w tablicy 'str' */
           sprintf(str,"%4.1f\xdf""C", temp);





           LCD_LOCATE(5,1);
          /* Wysyła komunikat do wyświetlacza */
           lcd_puts(str);
        }
      }
    }[

    Code:
    /*
    
       Plik ds18b20.h

       (xyz.isgreat.org) 
    */

    #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

    Code:
    /*
    
       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<9; 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;
    }

    Po ponownym utworzeniu całego projektu udało się skompilować. Ale na wyświetlaczu nie pojawiło się nic po kilku krotnym zresetowaniu układu pojawiło się ”?oC” czujnik jest podpięty według schematu z tamtej strony. Co mogę źle robić?

    0
  • #9 01 Sie 2012 21:25
    tronics
    Poziom 36  

    Teraz nie jestem 100% pewien, ale ostatnim razem jak robiłem coś na float to by to porządnie działało konieczne było podlinkowanie libm.

    0
  • #10 01 Sie 2012 22:46
    mirekk36
    Poziom 42  

    majki1995 napisał:
    Co mogę źle robić?


    Przede wszystkim to w ogóle zrezygnować z obliczeń na liczbach zmiennoprzecinkowych w takim prostym przypadku. Toż to aż woła o pomstę do nieba ;) żeby katować się tu z czymś takim.

    Poza tym ten kto pisał ten kod nawet nie zdaje sobie sprawy że w C dla AVR nie ma prawdziwego typu double ;) a takiego użył dla zmiennej temp. Została tylko nazwa tego typu aby zachować zgodność ze standardem ale nie ma wbudowanej obsługi liczb podwójnej precyzji to już by było w ogóle przegięcie. Dlatego typ double, w C dla AVR, działa dokładnie jak typ float (pojedyncza precyzja) ..... ale jak mówię używanie go w tym przypadku to wręcz jakaś niedorzeczność :( skoro równie dobrze na wyświetlacz czy gdziekolwiek można wyświetlić liczby zmiennoprzecinkowe posługując się jedynie liczbami całkowitymi.

    0
  • #11 01 Sie 2012 22:53
    pmt
    Poziom 12  

    Tak jak koledze wyżej u mnie też zdarzyło się, że podlinkowanie libm w podobnej sytuacji pomogło. Inną kwestią jest to, że ten program da się napisać bez użycia zmiennych zmiennoprzecinkowych: ciekawostka. Skutkuje to mniejszą objętością kodu i potencjalnie większą szybkością.

    EDIT
    Ups, widzę, że chwilę się spóźniłem, ale post z linkiem zostawiam. Może pomoże założycielowi wątku.

    0
  Szukaj w 5mln produktów