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

[ATmega8][C/C++][WinAVR] Jaki rodzaj zmiennej?

mufi 28 Gru 2008 07:36 1644 11
  • #1 5911440
    mufi
    Poziom 12  
    Mój problem polega na tym iż skopiowałem pewien program z kursu który na 100% działa.
    
    #define F_CPU 1000000L
    #include <avr/io.h>
    #include <avr/delay.h>
    
    int main(void)
    {
        /* Wszystkie linie portu D będą wyjściami */
        DDRD  = 0xFF;
    
        /* Początek nieskończonej pętli */
        for(;;)
        {
            PORTD = 0x0f;  /* Ładuje do PORTD wartość 0x0f*/
            /* opóźnienie 1 sek. */
            for(unsigned int i=0; i<100; i++) _delay_ms(10);
    
            PORTD |= 0xf0;  /* ustawia bity nr. 4..7 */
            for(unsigned int i=0; i<100; i++) _delay_ms(10);
    
            PORTD &= 0xaa;  /* zeruje bity nr. 0,2,4,6 */
            for(unsigned int i=0; i<100; i++) _delay_ms(10);
    
            PORTD ^= 0x0f;  /* "odwraca" bity nr. 0..3 */
            for(unsigned int i=0; i<100; i++) _delay_ms(10);
        
            PORTD = 0x00;
            /* opóźnienie 2 sek. */
            for(unsigned int i=0; i<200; i++) _delay_ms(10); 
        }
    }
    
    
    W kompilatorze (korzystam z kompilatora WinAVR-20050214) wyskakuje błąd:
    
    led.c:15: error: 'for' loop initial declaration used outside C99 mode
    led.c:18: error: redefinition of 'i'
    
    dla każej funkcji for.
    ------------------------------------------------------------------------
    Po zadeklarowaniu zmiennej 'i' przed funkcjami for, tzn tak:
    
    #define F_CPU 1000000L
    #include <avr/io.h>
    #include <avr/delay.h>
    
    int main(void)
    {
        /* Wszystkie linie portu D będą wyjściami */
        DDRD  = 0xFF;
    
        /* Początek nieskończonej pętli */
        for(;;)
        {
    	unsigned int i;
            PORTD = 0x0f;  /* Ładuje do PORTD wartość 0x0f*/
            /* opóźnienie 1 sek. */
            for(i=0; i<100; i++) _delay_ms(10);
    
            PORTD |= 0xf0;  /* ustawia bity nr. 4..7 */
            for(i=0; i<100; i++) _delay_ms(10);
    
            PORTD &= 0xaa;  /* zeruje bity nr. 0,2,4,6 */
            for(i=0; i<100; i++) _delay_ms(10);
    
            PORTD ^= 0x0f;  /* "odwraca" bity nr. 0..3 */
            for(i=0; i<100; i++) _delay_ms(10);
        
            PORTD = 0x00;
            /* opóźnienie 2 sek. */
            for(i=0; i<200; i++) _delay_ms(10); 
        }
    }
    

    program działa bez problemów:) Czy ktoś wie jakiego rodzaju ma być zmienna i lub jak ją zadeklarować (może brakuje jakiś nawiasów, znaczników, czegokolwiek akurat w tej wersji kompilatora) aby można było zapisać to tak:
    ....
    for (rodzaj_zmiennej i;........)
    {....

    przyzwyczaiłem się do tego rodzaju zapisu i chciałbym w ten sposób deklarować zmienne ale niestety nie wiem jak to zrobić :) Czy ktoś zna tajemnice o która mi chodzi?

    Kody źródłowe, proszę umieszczać w znacznikach[code]
    [zumek]
  • #2 5911611
    snow
    Poziom 31  
    U mnie (winavr20080610) kompiluje sie bez problemu (z jednym warningiem wynikającym z tego że delay.h zmienił katalog)
  • #3 5911764
    ginar
    Poziom 21  
    Też się kiedyś spotkałem z takim problemem, ale wtedy nie zastanawiałem się nad tym i zrobiłem tak jak w twoim programie.Składnia wydaje sie dobra, też jestem ciekaw skąd taki błąd.

    Btw: zamiast unsigned int i
    powinieneś stosować uint8_t i do tych pętli
  • #4 5911968
    BoskiDialer
    Poziom 34  
    Ja już dawno porzuciłem deklarowanie zmiennych w części inicjalizacji pętli for. Po opisie błędu można wnioskować, że owa zmienna mimo że zadeklarowana w pętli for, obowiązuje również poza pętlą, a więc deklarujesz ją kilka razy na tym samym poziomie, co nie jest dozwolone. Rozwiązanie pierwsze, to zmienną "i" deklarować tylko w pierwszej z pętli, rozwiązanie drugie, zalecane, deklarować zmienną "i" poza pętlami.
  • #5 5912072
    Dr.Vee
    VIP Zasłużony dla elektroda
    mufi - lepiej ściągnij sobie nowszą wersję kompilatora. A odpowiednia opcja dla kompilatora to -std=c99 lub -std=gnu99

    ginar - dla tak prostych pętli kompilator sam wykrywa, że może użyć typu o mniejszym zakresie (w tym przypadku właśnie uint8_t)

    BoskiDialer - wg. standardu C99 deklaracja zmiennej w nagłówku pętli obejmuje nagłówek + ciało pętli, a standard C89 nie zezwala na takie deklaracje.

    Pozdrawiam,
    Dr.Vee
  • #6 5912177
    BoskiDialer
    Poziom 34  
    Dr.Vee: Warto wiedzieć, nigdy nie chciało mi się wczytywać w dokładne standardy, zawsze pisałem żeby było jak najmniej ostrzeżeń (0). Jednak mój wywód z rozwiązaniami oparty był o komunikaty błędów. Deklarowanie zmiennej poza pętlami jest dla mnie wygodniejsze - bardzo często w moich programach wykorzystuję zmienną "i"(lub inną) poza pętlą. Również zalecam zaktualizowanie kompilatora.
  • #7 5913863
    mufi
    Poziom 12  
    Dr.Vee napisał:
    mufi - lepiej ściągnij sobie nowszą wersję kompilatora. A odpowiednia opcja dla kompilatora to -std=c99 lub


    mam już nową wersję :) ale jak tego użyć ? -std... nei wiem z czym to się je :)
  • #8 5913882
    skynet_2
    Poziom 26  
    w avrstudio w opcjach projektu, w custom options dorzuć do prawej tabeli.

    a się podepnę do tematu i o coś zapytam:

    czy zastosowanie jednej zmiennej[też stosuje "i" :)] i odwoływanie się do niej w każdej pętli będzie lepsze niż tworzenie zmiennej w każdej pętli.

    bo obydwa rozwiązania[za prostym przykładzie] zajmują tyle samo miejsca.
  • #9 5915350
    Dr.Vee
    VIP Zasłużony dla elektroda
    Jeśli nie używasz tej zmiennej nigdzie poza pętlą, to powinno być bez różnicy.

    Standard C99 pozwala na deklarację zmiennych nie tylko na początku bloku właśnie po to, żeby nie trzeba było wprowadzać dodatkowych bloków w celu ograniczenia zasięgu widoczności zmiennej. Im węższa widoczność, tym mniejsza szansa na pomyłkę.

    Pozdrawiam,
    Dr.Vee
  • #10 5916356
    skynet_2
    Poziom 26  
    Dr.Vee dzięki za szczególowe wyjaśnienie.
  • #11 5916523
    mufi
    Poziom 12  
    nie korzystam z AVRstudio :)
  • #12 5916621
    snow
    Poziom 31  
    W makefile jest:

    Cytat:

    # Compiler flag to set the C Standard level.
    # c89 = "ANSI" C
    # gnu89 = c89 plus GCC extensions
    # c99 = ISO C99 standard (not yet fully implemented)
    # gnu99 = c99 plus GCC extensions
    CSTANDARD = -std=gnu99
REKLAMA