RTV forum PL | NewsGroups PL

Sprawdzanie działania kodu do pomiaru częstotliwości sinusoidy 2-150Hz na ATmega128

AVR ATmega, pomiar częstotliwości przebiegu, prośba o spraw

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Sprawdzanie działania kodu do pomiaru częstotliwości sinusoidy 2-150Hz na ATmega128

Goto page Previous  1, 2, 3

Robbo
Guest

Fri Feb 11, 2011 1:22 pm   



Quote:
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.

Zbych
Guest

Fri Feb 11, 2011 1:24 pm   



W dniu 2011-02-11 12:05, Robbo pisze:
Quote:
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);
}

Zbych
Guest

Fri Feb 11, 2011 1:33 pm   



W dniu 2011-02-11 13:22, Robbo pisze:
Quote:
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.

Robbo
Guest

Fri Feb 11, 2011 1:58 pm   



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.

Robbo
Guest

Fri Feb 11, 2011 2:09 pm   



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.

Goto page Previous  1, 2, 3

elektroda NewsGroups Forum Index - Elektronika Polska - Sprawdzanie działania kodu do pomiaru częstotliwości sinusoidy 2-150Hz na ATmega128

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map