eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › avr i C - kto nie rozumie: kompilator, procesor czy ja?
Ilość wypowiedzi w tym wątku: 18

  • 1. Data: 2013-01-06 15:15:46
    Temat: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: Jakub Rakus <s...@o...pl>

    Witajcie,

    Ostatnie moje problemy (tu na grupie poruszane) z obsługą uarta na
    atmelkach stały się moim gwoździem do trumny bascoma i w końcu się
    zawziąłem na C, choć zabierałem się do tego już od roku jak pies do
    jeża. No to na początek, standardowo pomrugamy diodą. Ot taki programik:

    #define F_CPU 16000000UL
    #include <avr/io.h>
    #include <util/delay.h>
    int main(void)
    {
    DDRD = 0xFF;
    PORTD = 0x00;
    while(1)
    {
    PORTD ^= _BV(0);
    _delay_ms(500);
    }
    }

    I zonk, na porcie ciągle stan wysoki. Podejrzałem plik .lss i niby
    wszystko ok, jak patrzę na instrukcję asemblera to powinno działać:

    00000038 <main>:
    38: 8f ef ldi r24, 0xFF
    3a: 81 bb out 0x11, r24
    3c: 12 ba out 0x12, r1
    3e: 91 e0 ldi r25, 0x01
    40: 82 b3 in r24, 0x12
    42: 89 27 eor r24, r25
    44: 82 bb out 0x12, r24
    46: ef ef ldi r30, 0xFF
    48: ff e3 ldi r31, 0x3F
    4a: 31 97 sbiw r30, 0x01
    4c: f1 f7 brne .-4
    4e: 00 c0 rjmp .+0
    50: f7 cf rjmp .-18

    Ale niestety nie działa, stan na porcie zmienia się bez opóźnienia. A
    teraz ciekawostka, zamiast wykorzystywać funkcję _delay_ms wstawiłem swoją:

    void delay(void)
    {
    uint16_t i;
    for (i=0;i<15000;i++);
    }

    Patrzę na plik .lss, a tu:

    00000038 <delay>:
    38: 88 e9 ldi r24, 0x98
    3a: 9a e3 ldi r25, 0x3A
    3c: 01 97 sbiw r24, 0x01
    3e: f1 f7 brne .-4
    40: 08 95 ret
    00000042 <main>:
    42: 8f ef ldi r24, 0xFF
    44: 81 bb out 0x11, r24
    46: 12 ba out 0x12, r1
    48: 91 e0 ldi r25, 0x01
    4a: 82 b3 in r24, 0x12
    4c: 89 27 eor r24, r25
    4e: 82 bb out 0x12, r24
    50: fc cf rjmp .-8

    Wychodzi na to, że po przełączeniu bitu PD0 w ogóle nie wywołuje funkcji
    delay() - no i port tak właśnie się zachowuje, w kółko się przełącza.

    Obstawiam opcję, że ja czegoś nie rozumie, ale może ktoś mnie oświeci.

    --
    Pozdrawiam
    Jakub Rakus


  • 2. Data: 2013-01-06 15:26:23
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: Marek <f...@f...com>

    On Sun, 06 Jan 2013 15:15:46 +0100, Jakub Rakus <s...@o...pl>
    wrote:
    > Wychodzi na to, że po przełączeniu bitu PD0 w ogóle nie wywołuje
    funkcji
    > delay() - no i port tak właśnie się zachowuje, w kółko się
    przełącza.

    Nie użyłeś volatile przy deklaracji zmiennej "i" w funkcji delay(),
    "i" nie jest nigdzie wykorzystane dalej w kodzie funkcji więc
    optymalizator wywalił cały for, jak nie potrzebny for to i cała
    funkcja delay()...

    --
    Marek


  • 3. Data: 2013-01-06 15:29:38
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: "Grzegorz Niemirowski" <g...@p...onet.pl>

    Jakub Rakus <s...@o...pl> napisał(a):
    > Witajcie,
    > Ostatnie moje problemy (tu na grupie poruszane) z obsługą uarta na
    > atmelkach stały się moim gwoździem do trumny bascoma i w końcu się
    > zawziąłem na C, choć zabierałem się do tego już od roku jak pies do jeża.

    A problem był po stronie Bascoma czy niedopracowanego algorytmu?

    > No to na początek, standardowo pomrugamy diodą. Ot taki programik:
    > #define F_CPU 16000000UL
    > #include <avr/io.h>
    > #include <util/delay.h>
    > int main(void)
    > {
    > DDRD = 0xFF;
    > PORTD = 0x00;
    > while(1)
    > {
    > PORTD ^= _BV(0);
    > _delay_ms(500);
    > }
    > }
    > I zonk, na porcie ciągle stan wysoki. Podejrzałem plik .lss i niby
    > wszystko ok, jak patrzę na instrukcję asemblera to powinno działać:
    > 00000038 <main>:
    > 38: 8f ef ldi r24, 0xFF
    > 3a: 81 bb out 0x11, r24
    > 3c: 12 ba out 0x12, r1
    > 3e: 91 e0 ldi r25, 0x01
    > 40: 82 b3 in r24, 0x12
    > 42: 89 27 eor r24, r25
    > 44: 82 bb out 0x12, r24
    > 46: ef ef ldi r30, 0xFF
    > 48: ff e3 ldi r31, 0x3F
    > 4a: 31 97 sbiw r30, 0x01
    > 4c: f1 f7 brne .-4
    > 4e: 00 c0 rjmp .+0
    > 50: f7 cf rjmp .-18
    > Ale niestety nie działa, stan na porcie zmienia się bez opóźnienia. A
    > teraz ciekawostka, zamiast wykorzystywać funkcję _delay_ms wstawiłem
    > swoją:
    > void delay(void)
    > {
    > uint16_t i;
    > for (i=0;i<15000;i++);
    > }
    > Patrzę na plik .lss, a tu:
    > 00000038 <delay>:
    > 38: 88 e9 ldi r24, 0x98
    > 3a: 9a e3 ldi r25, 0x3A
    > 3c: 01 97 sbiw r24, 0x01
    > 3e: f1 f7 brne .-4
    > 40: 08 95 ret
    > 00000042 <main>:
    > 42: 8f ef ldi r24, 0xFF
    > 44: 81 bb out 0x11, r24
    > 46: 12 ba out 0x12, r1
    > 48: 91 e0 ldi r25, 0x01
    > 4a: 82 b3 in r24, 0x12
    > 4c: 89 27 eor r24, r25
    > 4e: 82 bb out 0x12, r24
    > 50: fc cf rjmp .-8
    > Wychodzi na to, że po przełączeniu bitu PD0 w ogóle nie wywołuje funkcji
    > delay() - no i port tak właśnie się zachowuje, w kółko się przełącza.
    > Obstawiam opcję, że ja czegoś nie rozumie, ale może ktoś mnie oświeci.

    Ustawiłeś optymalizacje zgodnie z dokumentacją?
    Którego kompilatora używasz?

    --
    Grzegorz Niemirowski
    http://www.grzegorz.net/
    OE PowerTool i Outlook Express: http://www.grzegorz.net/oe/
    Uptime: 0 days, 1 hours, 26 minutes and 32 seconds


  • 4. Data: 2013-01-06 15:45:11
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: Jakub Rakus <s...@o...pl>

    W dniu 06.01.2013 15:26, Marek pisze:

    > Nie użyłeś volatile przy deklaracji zmiennej "i" w funkcji delay(), "i"
    > nie jest nigdzie wykorzystane dalej w kodzie funkcji więc optymalizator
    > wywalił cały for, jak nie potrzebny for to i cała funkcja delay()...

    Ooo, no to jest racja, nie pomyślałem. Faktycznie, dodaję volatile,
    wtedy śmiga. Podziękował!
    Ale nadal pozostaje problem nie działającej funkcji _delay_ms().

    --
    Pozdrawiam
    Jakub Rakus


  • 5. Data: 2013-01-06 15:57:45
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: Jakub Rakus <s...@o...pl>

    W dniu 06.01.2013 15:29, Grzegorz Niemirowski pisze:
    >
    > A problem był po stronie Bascoma czy niedopracowanego algorytmu?
    >
    Problem polegał na tym, że pomimo wielu prób nie doszedłem do tego jak
    stworzyć poprawnie działający algorytm pisząc go tylko w bascomie, nie
    angażując w to asemblera, a nie miałem na to ochoty ;) - poza tym po
    skompilowaniu miałem i tak już ogromny program (3kB!), a w planie
    jeszcze kilka funkcjonalności, więc i tak bym doszedł do granicy
    możliwości darmowego bascoma.
    >
    > Ustawiłeś optymalizacje zgodnie z dokumentacją?
    > Którego kompilatora używasz?
    >
    Korzystam z code::blocks i avr-gcc w wersji 4.5.3. Ustawiam
    optymalizację na -O. Co ciekawe, gdy wyłączę optymalizację w ogóle,
    oczywiście mam ostrzeżenie, że funkcje z delay.h będą działać
    niepoprawnie, kompiluje się, program wynikowy jest ogromny, ale... działa.

    --
    Pozdrawiam
    Jakub Rakus


  • 6. Data: 2013-01-06 16:01:09
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: Marek <f...@f...com>

    On Sun, 06 Jan 2013 15:45:11 +0100, Jakub Rakus <s...@o...pl>
    wrote:
    > Ale nadal pozostaje problem nie działającej funkcji _delay_ms().

    Zgaduje teraz (nie znam się na avr), czy czasem nie potrzeba
    wcześniej wywolac jakaś funkcję konfigurujaca bibliotekę wszystkich
    funkcji delay? Skąd delay wie jaka jest aktualna częstotliwość
    zegara?

    --
    Marek


  • 7. Data: 2013-01-06 16:09:35
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: Jakub Rakus <s...@o...pl>

    W dniu 06.01.2013 16:01, Marek pisze:
    > On Sun, 06 Jan 2013 15:45:11 +0100, Jakub Rakus <s...@o...pl> wrote:
    >> Ale nadal pozostaje problem nie działającej funkcji _delay_ms().
    >
    > Zgaduje teraz (nie znam się na avr), czy czasem nie potrzeba wcześniej
    > wywolac jakaś funkcję konfigurujaca bibliotekę wszystkich funkcji delay?
    > Skąd delay wie jaka jest aktualna częstotliwość zegara?
    >

    Zgodnie z tym co napisano na początku delay.h wystarczająca jest
    linijka, którą mam na początku kodu:

    #define F_CPU 16000000UL

    A nawet gdyby jej nie było to przyjmie sobie domyślną wartość F_CPU
    1000000UL.

    --
    Pozdrawiam
    Jakub Rakus


  • 8. Data: 2013-01-06 16:58:31
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: "Grzegorz Niemirowski" <g...@p...onet.pl>

    Jakub Rakus <s...@o...pl> napisał(a):
    > Korzystam z code::blocks i avr-gcc w wersji 4.5.3. Ustawiam optymalizację
    > na -O. Co ciekawe, gdy wyłączę optymalizację w ogóle, oczywiście mam
    > ostrzeżenie, że funkcje z delay.h będą działać niepoprawnie, kompiluje
    > się, program wynikowy jest ogromny, ale... działa.

    Nie wiem, co u Ciebie dokładnie oznacza -O, u mnie jest to -O1. Twój program
    działa bez żadnego problemu u mnie na ATmega32 (może kompilujesz na zły
    procesor). Używam Atmel Studio 6 (
    AVR/GNU C Compiler : (AVR_8_bit_GNU_Toolchain_3.4.0_663) 4.6.2)
    Poza tym w pierwszym poście piszesz: "I zonk, na porcie ciągle stan wysoki."
    z czego wynika, że u Ciebie w ogóle nie wykonuje się pętla while.
    Mój lss:
    00000092 <main>:
    #define F_CPU 16000000UL
    #include <avr/io.h>
    #include <util/delay.h>
    int main(void)
    {
    DDRD = 0xFF;
    92: 8f ef ldi r24, 0xFF ; 255
    94: 81 bb out 0x11, r24 ; 17
    PORTD = 0x00;
    96: 12 ba out 0x12, r1 ; 18
    while(1)
    {
    PORTD ^= _BV(0);
    98: 91 e0 ldi r25, 0x01 ; 1
    9a: 82 b3 in r24, 0x12 ; 18
    9c: 89 27 eor r24, r25
    9e: 82 bb out 0x12, r24 ; 18
    #else
    //round up by default
    __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
    #endif
    __builtin_avr_delay_cycles(__ticks_dc);
    a0: 2f ef ldi r18, 0xFF ; 255
    a2: 39 e6 ldi r19, 0x69 ; 105
    a4: 48 e1 ldi r20, 0x18 ; 24
    a6: 21 50 subi r18, 0x01 ; 1
    a8: 30 40 sbci r19, 0x00 ; 0
    aa: 40 40 sbci r20, 0x00 ; 0
    ac: e1 f7 brne .-8 ; 0xa6 <main+0x14>
    ae: 00 c0 rjmp .+0 ; 0xb0 <main+0x1e>
    b0: 00 00 nop
    b2: f3 cf rjmp .-26 ; 0x9a <main+0x8>
    000000b4 <_exit>:
    b4: f8 94 cli
    000000b6 <__stop_program>:
    b6: ff cf rjmp .-2 ; 0xb6 <__stop_program>


    --
    Grzegorz Niemirowski
    http://www.grzegorz.net/
    OE PowerTool i Outlook Express: http://www.grzegorz.net/oe/
    Uptime: 0 days, 0 hours, 6 minutes and 49 seconds


  • 9. Data: 2013-01-06 17:28:40
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: Jakub Rakus <s...@o...pl>

    W dniu 06.01.2013 16:58, Grzegorz Niemirowski pisze:

    > Nie wiem, co u Ciebie dokładnie oznacza -O, u mnie jest to -O1.
    Zjadła się jedynka, też mam -O1.

    > Poza tym w pierwszym poście piszesz: "I zonk, na porcie ciągle stan
    > wysoki." z czego wynika, że u Ciebie w ogóle nie wykonuje się pętla while.
    Zasugerowałem się tym, że leda mi ciągle świeci, ale faktycznie pętla
    się wykonuje - tylko, że cholernie szybko...

    > //round up by default
    > __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
    > #endif
    > __builtin_avr_delay_cycles(__ticks_dc);
    > a0: 2f ef ldi r18, 0xFF ; 255
    > a2: 39 e6 ldi r19, 0x69 ; 105
    > a4: 48 e1 ldi r20, 0x18 ; 24
    > a6: 21 50 subi r18, 0x01 ; 1
    > a8: 30 40 sbci r19, 0x00 ; 0
    > aa: 40 40 sbci r20, 0x00 ; 0
    > ac: e1 f7 brne .-8 ; 0xa6 <main+0x14>
    > ae: 00 c0 rjmp .+0 ; 0xb0 <main+0x1e>

    O widzisz tu właśnie jest rozbieżność - u Ciebie jak widzę działa to
    dokładnie tak jak opisane jest to na początku delay.h. U mnie
    _HAS_DELAY_CYCLES ma wartość 1, więc teoretycznie także powinna zostać
    wywołana funkcja _builtin_avr_delay_cycles, a z jakiegoś powodu tak się
    nie dzieje.

    --
    Pozdrawiam
    Jakub Rakus


  • 10. Data: 2013-01-06 17:46:23
    Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
    Od: "Grzegorz Niemirowski" <g...@p...onet.pl>

    Jakub Rakus <s...@o...pl> napisał(a):
    > O widzisz tu właśnie jest rozbieżność - u Ciebie jak widzę działa to
    > dokładnie tak jak opisane jest to na początku delay.h. U mnie
    > _HAS_DELAY_CYCLES ma wartość 1, więc teoretycznie także powinna zostać
    > wywołana funkcja _builtin_avr_delay_cycles, a z jakiegoś powodu tak się
    > nie dzieje.

    A czy ten Twój toolchain ma w ogóle tę funkcję? I dlaczego użwasz akurat
    tego toolchaina a nie np. Atmel Studio 6 albo WinAVR?

    --
    Grzegorz Niemirowski
    http://www.grzegorz.net/
    OE PowerTool i Outlook Express: http://www.grzegorz.net/oe/
    Uptime: 0 days, 0 hours, 57 minutes and 50 seconds

strony : [ 1 ] . 2


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: