Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

AVR dziwne liczby, mnożenie

ginar 17 Lis 2008 10:31 2040 8
  • #1 17 Lis 2008 10:31
    ginar
    Poziom 21  

    Witam
    Od dłuższego czasu nie mogę dojść co jest nie tak:
    set_Freq[] - typu int
    set_Freq[x]- przyjmuje cyfry od 0..9
    unsigned long int SET

    zamienia wprowadzone cyfry na liczbę
    kawałek kodu:

    Code:

        SET =set_Freq[0]+10*set_Freq[1]+100*set_Freq[2]+1000*set_Freq[3]+10000*set_Freq[4]+100000*set_Freq[5]+1000000*set_Freq[6];
    //poniżej to tylko wyswietlenie     
    Command_LCD(2 ,86);
        dtostrf(SET,1,0,table_y);
     WriteText_LCD(table_y);
    while(1){};

    w takiej formie zmienna SET zawsze ma błąd na 5 pozycji. jesli próbuje sie wpisać na tą pozycję cyfrę >3. Pozostałe pozycje/wagi (wyzsze lub niższe są ok).

    próbowałem również ręcznie w programie wpisać:
    np.
    Code:

    SET =60000;
    ....
       

    i to jest ok. ale już
    Code:

    SET =10000*6;
    ....
       

    daje dziwną liczbę 4294961929

    dla SET =10000*4;
    4294941425
    dla SET =10000*5;
    42949514378

    używam bibliotek:

    #include <avr/io.h>
    #include <avr/delay.h>
    #include <Function_AD9833.c> //dołączana biblioteka obsługi AD9833 z katalogu
    #include <LCD_HD44780.c> //dołączana biblioteka obsługi LCD z katalogu
    #include <stdio.h>
    #include <inttypes.h>
    #include <avr/interrupt.h> //obsługa przerwań
    #include <avr/signal.h>

  • #2 17 Lis 2008 10:47
    szelus
    Specjalista - Mikrokontrolery

    Zakresy wartości. Zmień 10000 na 10000UL.

    P.S. Po co konwerujesz SET na zmienny przecinek przed konwersją na string? Nie lepiej użyć ltoa()?

  • #3 17 Lis 2008 12:37
    zumek
    Poziom 39  

    A po jakie licho, tworzyć takiego gigantycznego stwora :?:

    Code:
     SET=set_Freq[0]+10*set_Freq[1]+100*set_Freq[2]+1000*set_Freq[3]+10000*set_Freq[4]+100000*set_Freq[5]+1000000*set_Freq[6];
    
    //poniżej to tylko wyswietlenie

    Ani to "ładne", ani "pamięciooszczędne" :-P
    Prosta pętla, załatwi to bezbłędnie i oszczędnie:
    Code:

       SET=0;
       for(i=0;i<x;i++)
       {
          SET=SET*10+set_Freq[i];
       }

    Poza tym:
    Code:

    set_Freq[] - typu int
    set_Freq[x]- przyjmuje cyfry od 0..9
    unsigned long int SET
     

    Po co sys_Freq[] jest typu int :?: Marnotrawstwo pamięci danych.
    szelus napisał:
    P.S. Po co konwerujesz SET na zmienny przecinek przed konwersją na string? Nie lepiej użyć ltoa()?

    Autor tematu ma chyba kłopoty, z rozróżnianiem typu danych, bo do funkcji dtostrf (double __val, signed char __width, unsigned char __prec, char *__s),
    zamiast double podstawia unsigned long, a potem sie dziwi , że widzi cuda na LCD. O ostrzeżeniach kompilatora , wogóle nie wspomina - dziwne :|

    Piotrek

  • #4 19 Lis 2008 00:48
    ginar
    Poziom 21  

    Po zamianie 10000 na 10000ul , działa ok.
    Mógłby ktoś objaśnić podać lika , dlaczego tak się działo?

    Cytat:
    Po co sys_Freq[] jest typu int Question Marnotrawstwo pamięci danych.
    zgadzam się, w rzeczywistym programie używam typów uintx_t .

  • #5 19 Lis 2008 10:33
    szelus
    Specjalista - Mikrokontrolery

    To już było tyle razy...

    W C niejawna promocja typów int w wyrazeniu następuje tylko, jeżeli jeden z operandów jest typu o większym zakresie wartości, a nie kiedy wynik operacji może przekroczyć zakres typu. Ten drugi przypadek spada na programistę.

    Wiesz oczywiście, ża na AVR int to maksymalnie 32767? No to literał 10000 jest typu int. Jak pomnożysz przez inny int, który jest większy od 3, to przekroczysz zakres. 10000ul jest typu unsigned long i wymusi pomocję drugiego operandu do typu unsigned long przed wykonaniem mnożenia.
    Proste?

  • #6 19 Lis 2008 11:25
    ginar
    Poziom 21  

    Cytat:
    Wiesz oczywiście, ża na AVR int to maksymalnie 32767

    w tym własnie problem..
    z tego co napisałeś podejrzewam, że na int przychodzi 16 bitów (bit znaku i 15 bitów na wartość ) co by wychodziło 2^16 różnych warości.
    na PC to chyba można uzyć do tego celu funkcji sizeof ,aby wiedzieć ile bitów przypada na dany typ zmiennej, a jak to można sprawdzić na AVR?

  • Pomocny post
    #7 19 Lis 2008 12:28
    szelus
    Specjalista - Mikrokontrolery

    ginar napisał:

    na PC to chyba można uzyć do tego celu funkcji sizeof ,aby wiedzieć ile bitów przypada na dany typ zmiennej,

    sizeof należy chyba do standardu C, nieprawdaż?
    Cytat:

    a jak to można sprawdzić na AVR?

    Przeczytać w instrukcji?
    Przejrzeć zawartość pliku stdint.h?

  • #8 19 Lis 2008 14:49
    Dr.Vee
    VIP Zasłużony dla elektroda

    I na przyszłość nie używać w systemach wbudowanych char, short, int, long, tylko [u]int{8,16,32}_t zdefiniowanych w pliku stdint.h

    Pozdrawiam,
    Dr.Vee

  • #9 19 Lis 2008 15:59
    ginar
    Poziom 21  

    dzieki, rzeczywiscie w stdint.h jest wszystko opisane

    Cytat:
    I na przyszłość nie używać w systemach wbudowanych char, short, int, long, tylko [u]int{8,16,32}_t zdefiniowanych w pliku stdint.h
    tak tez mam zamiar zrobic, wtedy bedzie przejzyszcie
    Pozdr.

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME