eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Ilość wypowiedzi w tym wątku: 35

  • 31. Data: 2011-02-11 12:22:23
    Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
    Od: "Robbo" <y...@m...com>

    >Zamiast tego posłuż się ATOMIC_BLOCK


    Zrobiłem tak:

    while (1) {
    ATOMIC_BLOCK(ATOMIC_FORCEON) {
    actualDurationLatch = actualDuration;
    }

    sprintf(s, "%d %ld ", i++, actualDurationLatch);
    LCDwriteString(s);
    }

    W Makefile dałem -std=gnu99.

    Efekt jest taki, że na wyświetlaczu widzę cały czas zwiększającą się wartość
    zmiennej "i". Natomiast actualDurationLatch przyjmuje jakąś wartość i tak
    już trwa -- nie reaguje na zmianę częstotliwości. Gdy wyrzucę ATOMIC_BLOCK,
    to actualDurationLatch ożywa.

    R.


  • 32. Data: 2011-02-11 12:24:36
    Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
    Od: Zbych <a...@o...pl>

    W dniu 2011-02-11 12:05, Robbo pisze:
    >> Jak już muszę użyć to często robię unię zmiennej volatile i bez
    >> volatile. Dzięki czemu nie mam nadmiarowego kodu np. w przerwaniach.
    >
    > Gdybyś mógł wyjaśnić, co daje taka konstrukcja...?

    W ogólności krótszy/szybszy kod. Użycie volatile to zakaz optymalizacji
    dla kompilatora. Poniżej masz prosty przykład z odmierzaniem opóźnienia
    przez przerwanie timera. Gdyby zmienna była volatile, to w przerwaniu
    musiałbyś ją pobrać dwa razy.

    union{
    volatile uint8_t V;
    uint8_t NV;
    }aqq;


    ISR(od_jakiegos_timera){
    if (aqq.NV != 0) aqq.NV--;
    }

    main(){

    aqq.V = 100;
    while(aqq.V != 0);
    }


  • 33. Data: 2011-02-11 12:33:03
    Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
    Od: Zbych <a...@o...pl>

    W dniu 2011-02-11 13:22, Robbo pisze:
    >> Zamiast tego posłuż się ATOMIC_BLOCK
    >
    >
    > Zrobiłem tak:
    >
    > while (1) {
    > ATOMIC_BLOCK(ATOMIC_FORCEON) {
    > actualDurationLatch = actualDuration;
    > }
    >
    > sprintf(s, "%d %ld ", i++, actualDurationLatch);
    > LCDwriteString(s);
    > }
    >
    > W Makefile dałem -std=gnu99.
    >
    > Efekt jest taki, że na wyświetlaczu widzę cały czas zwiększającą się
    > wartość zmiennej "i". Natomiast actualDurationLatch przyjmuje jakąś
    > wartość i tak już trwa -- nie reaguje na zmianę częstotliwości. Gdy
    > wyrzucę ATOMIC_BLOCK, to actualDurationLatch ożywa.

    Dopisz do swojego programu dwie linie:

    while (1) {
    asm volatile(";ala ma kota - start"); //<----------------
    ATOMIC_BLOCK(ATOMIC_FORCEON) {
    actualDurationLatch = actualDuration;
    }
    asm volatile(";ala ma kota - stop"); //<----------------

    sprintf(s, "%d %ld ", i++, actualDurationLatch);
    LCDwriteString(s);
    }

    Skompiluj, otwórz plik *.lss, który zawiera program po deasemblacji,
    poszukaj ciągu "ala ma kota" i porównaj czym wersja z ATOMIC różni się
    od wersji bez ATOMIC.


  • 34. Data: 2011-02-11 12:58:27
    Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
    Od: "Robbo" <y...@m...com>

    Dzięki za wyjaśnienie.
    Sprawdziłem...

    union{
    volatile uint8_t V;
    uint8_t NV;
    }aqq;


    ISR(od_jakiegos_timera){
    if (aqq.NV != 0) aqq.NV--;
    }

    main(){

    aqq.V = 100;
    while(aqq.V != 0);
    }

    Daje kod dla ISR():
    push r1
    push r0
    in r0, 0x3f
    push r0
    eor r1, r1
    push r24

    lds r24,0x0100
    and r24, r24
    breq .+6
    subi r24, 0x01
    sts 0x0100, r24

    pop r24
    pop r0
    out 0x3f, r0
    pop r0
    pop r1
    reti

    ----------------

    Natomiast program:

    volatile uint8_t V;

    ISR(od_jakiegos_timera){
    if (V != 0) V--;
    }

    main(){

    V = 100;
    while(V != 0);
    }

    Daje kod dla ISR():
    push r1
    push r0
    in r0, 0x3f
    push r0
    eor r1, r1
    push r24

    lds r24,0x0100
    and r24, r24
    breq .+10
    lds r24, 0x0100
    subi r24, 0x01
    sts 0x0100, r24

    pop r24
    pop r0
    out 0x3f, r0
    pop r0
    pop r1
    reti


    ---

    Mam pytanie. Czy do tych "sztuczek" sam dochodziłeś, czy też mógłbyś polecić
    jakieś książki/tutoriale dotyczące optymalizacji kodu dla mikrokontrolerów?

    R.


  • 35. Data: 2011-02-11 13:09:41
    Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
    Od: "Robbo" <y...@m...com>

    Z ATOMIC i bez ATOMIC wygląda tak samo:

    lds r24, 0x052f
    lds r25, 0x0530
    lds r26, 0x0531
    lds r27, 0x0532
    sts 0x029e, r24
    sts 0x029f, r25
    sts 0x02a0, r26
    sts 0x02a1, r27

    Ale zauważyłem (patrząc w plik main.lst), że użycie ATOMIC spowodowało, iż
    przed pętlą while (1) znalazło się iCliRetVal:

    static __inline__ uint8_t __iCliRetVal(void)
    {
    cli();

    while (1) {

    asm volatile(";ala ma kota - start"); //<--------
    ATOMIC_BLOCK(ATOMIC_FORCEON) {
    actualDurationLatch = actualDuration;
    ...

    R.

strony : 1 ... 3 . [ 4 ]


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: