Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

AVR M32 ASM - ASM flaga C

ASMnauka 29 Mar 2013 18:45 2118 15
  • #1 29 Mar 2013 18:45
    ASMnauka
    Poziom 12  

    Bardzo proszę o pomoc w zrozumieniu działania tej pętli.

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    SER = Ustaw rejestr gdzie Rh<-$FF/
    LDI = Załaduj do rejestru stałą bezpośrednią.
    SUBI = Odejmij stałą od rejestru.
    SBCI = Odejmij stałą wraz z C od rejestru.
    BRNE = Wykonaj skok tylko gdy różne.

    Nie wiem za bardzo o chodzi z tą flagą C.
    Poza tym wprowadzona do rejestrów R17 i R18 jest liczbą typu LONG (230400)
    Inna sprawa, że SUBI odejmuje tylko od liczby 255.
    Natomiast SBCI w tym przypadku odejmuje ZERO.

    Proszę o pomoc.

    0 15
  • #3 29 Mar 2013 19:12
    ASMnauka
    Poziom 12  

    dondu, właśnie przeglądam te PDF-y, owszem, dla Ciebie jest wszystko jasne, jeśli to już rozumiesz.

    Proszę, oto przykład z jednego z nich.

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    Ten akurat przykład już zrozumiałem, ale w pętli którą podałem wcześniej jest to zagnieżdżone.

    0
  • #4 29 Mar 2013 19:24
    BlueDraco
    Specjalista - Mikrokontrolery

    Nic tam nie jest zagnieżdżone. Jest 24-bitowy licznik pętli, zawarty w rejestrach r18:r17:r16. Te trzyinstrukcje po prostu odejmują jedynkę od zmiennej 24-bitowej, a ostania - zamyka pętlę jeśli nie osiągnięto wartości zero. To przykład, jak nie należy robić opóźnień w programach. ;)

    0
  • #5 29 Mar 2013 19:44
    ASMnauka
    Poziom 12  

    No tak, ale do rejestru R17 została w tym przykładzie wprowadzona liczba 132 (HEX 84)
    Natomiast do rejestru R18 liczba 3 (HEX03)
    W jaki sposób zmienić liczbę 230400 by ja zmieścić w dwóch rejestrach, jeśli jest liczbą typu LONG ?
    Jeśli w tym przykładzie odejmuje się od rejestru R16 1 (SUBI r16, 1) a załadowano do tego rejestru 255 więc jak to jest dalej z tym odliczaniem ?

    0
  • #6 29 Mar 2013 19:50
    BlueDraco
    Specjalista - Mikrokontrolery

    Do trzech rejestrów razem została zapisana jakaś liczba 24-bitowe, i ta liczba jest w pętli dekrementowana. Ponieważ w AVR nie ma instrukcji zapisu 24 bitów do trzech rejestrów, więc do każdego rseejtru oddzielną instrukcją zapisano odpowiedni oktet tej 24-bitowej liczby.

    230400 nie mieści się w dwóch rejestrach 8-bitowych. Zapisz sobie jej reprezentację bitową, potem potnij na kawałki po 8 bitów - otrzymasz 3 bajty, z których składa się ta liczba (czwarty i następne byłyby zerami, bo ta liczba ma 18 bitów znaczących.

    0
  • #7 29 Mar 2013 19:56
    ASMnauka
    Poziom 12  

    Czy jest może jakiś sposób, by to obliczyć w liczbach DEC ?
    Czy mogę ładować do rejestrów zarówno liczby w formie HEX, jak i BIN i DEC ?

    0
  • #8 29 Mar 2013 20:12
    tmf
    Moderator Mikrokontrolery Projektowanie

    Format zapisu jest bez znaczenia, procesor i tak rozumie tylko jeden - binarny. To czy to sobie zapiszesz jako hex, dec czy oct, to tylko dla twojej wygody jest. Jeśli chcesz rozbić liczbę 24-bitową na poszczególne bajty, to najmłodszy masz liczba%256, starszy (liczba/256)%256, a najstarszy (liczba/65536)%256. W asemblerze masz też gotowce, typu high, low itd. Zobacz na dyrektywy asemblera.

    0
  • #9 29 Mar 2013 20:17
    ASMnauka
    Poziom 12  

    TMf co znaczy % ?
    Jest to procent z liczby przy dzieleniu na trzy bajty ?
    Wiem, że można zapisywać do rejestrów liczbę 16 bitową rozbijając ją na starsze i młodsze bajty.
    high z liczby LONG ?

    0
  • #10 29 Mar 2013 20:22
    BlueDraco
    Specjalista - Mikrokontrolery

    Do rejestrów ładuje się liczby wyłączenie w postaci binarnej, bo procesor nie wie, co to jest system dziesiętny. W tekście programu możesz te liczby zapisać w postaci binarnej, dziesiętnej, szesnastkowej, ósemkowej albo jako znaki - 'a', '5' itd. Możesz również zapisywać je jako wyrażenia stałe, np. 5 + 77 albo '5' - 15.
    Nie znam asemblera AVR, ale zapewne jest w nim jakiś sposób na to, żeby zapisać to po ludzku, bez konieczności wyliczania wartości bajtów przez programistę.
    W C wyglądałoby to np. tak:
    #define LICZNIK
    uint8_t b0, b1, b2;
    b0 = LICZNIK; // najmniej znaczący bajt
    b1 = LICZNIK >> 8;
    b2 = LICZNIK >> 16;

    Swoją drogą naprawdę nie rozumiem, dlaczego uczysz się asemblera AVR. Architektura lekko podstarzała, zaprojektowana z myślą o wygodnym programowaniu w C i całkiem nieprzyjemna do programowania asemblerowego. Trudno wskazać istotne korzyści z programowania asemblerowego AVR, zresztą podobnie jak w przypadku ARMów. Jeśli już bardzo chcesz zgłębiać jakiś asembler, to radziłbym raczej na PC - x86.

    0
  • #11 29 Mar 2013 20:50
    ASMnauka
    Poziom 12  

    Z tego co pamiętam, przesuwasz bity w liczbie, czy dobrze pamiętam ?

    Dodano po 19 [minuty]:

    tmf, czyli np. zapis

    Kod: asm
    Zaloguj się, aby zobaczyć kod

    jest jak najbardziej zrozumiały dla M32 ?

    0
  • #12 29 Mar 2013 21:03
    tmf
    Moderator Mikrokontrolery Projektowanie

    Ten % to modulo. Twój zapis nie jest zrozumiały, bo nie ma instrukcji PUT. Jest np. STS DDRD, r16, pod warunkiem, że sobie definicje rejestrów zainkludujesz.

    0
  • #13 29 Mar 2013 21:19
    ASMnauka
    Poziom 12  

    Przepraszam, zamiast PUT powinno być OUT

    0
  • Pomocny post
    #14 29 Mar 2013 22:23
    excray
    Poziom 39  

    Do przeliczania DEC - HEX użyj choćby windowsowego kalkulatora. Jak wybierzesz widok->programisty to możesz przeliczać min dec-hex-bin-oct. Jak wpiszesz decymalnie 230400 i przeliczysz na hex to otrzymasz 38400 czyli rozpisując na 3 bajty 0x03 0x84 i 0x00. Co do kodu:
    SUBI r16, 1 - odejmuje od r16 wartość 1. Flaga C nie jest w tym przypadku brana pod uwagę przy odejmowaniu. W przypadku gdy r16 = 0 operacja ta spowoduje ustawienie flagi C
    SBCI r17, 0 - odejmuje od r17 wartość (0 + C) czyli zazwyczaj operacja ta nic nie zmienia. Dopiero gdy poprzednia operacja ustawi C wartość r17 zmniejszy się o 1. To tak samo jak w systemie dziesiętnym. Jak od 20 odejmiesz 1 to nie możesz mieć dalej dwójki na początku. Nie możesz uzyskać 29. Musisz od dziesiątek odjąć 1. Tak samo jest tutaj z r16 i r17. W momencie gdy r16 (który tutaj reprezentuje tak jakby jednostki) zejdzie do zera to po następnym odejmowaniu musimy zmniejszyć r17 który tak jakby reprezentuje dziesiątki. Wszystko dzieje się za pośrednictwem flagi C która mówi że w poprzednim działaniu wyszliśmy poza maksymalny (od góry albo od dołu) zakres danej wartości.
    A wracając do samego przeliczania - jak kiedyś będziesz używał 16-to bitowych stałych to zamiast przeliczać kalkulatorem możesz wysłużyć się kompilatorem zapisując to tak:
    //32348 = 0x7E5C
    ldi r16,low(32348) //w r16 zostanie wpisane 0x5C
    ldi r17,high(32348) //w r17 -||- 0x7E

    0
  • #15 30 Mar 2013 13:05
    ASMnauka
    Poziom 12  

    Chyba zrozumiałem zasadę działania pętli, którą przedstawiłem wcześniej.
    Napisałem dwie małe pętle.

    Pierwsza:

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    I druga:

    Kod: asm
    Zaloguj się, aby zobaczyć kod

    Obie pętle wykonja sie tylko 10 razy.
    W drugiej pętli muszę odkładać na stos rejestr R30.
    Jeśli go nie odłożę pętla nie wykonuje się poprawnie.
    Co jest tego powodem ?
    Nie ma tam przerwania, jest tylko skok do etykiety.

    Czy istnieje możliwość programowego rozdzielenia liczby czterobajtowej ? (LONG)

    0
  • #16 30 Mar 2013 13:58
    excray
    Poziom 39  

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    A tutaj:
    Kod: asm
    Zaloguj się, aby zobaczyć kod

    wszystko nadaje się do kosza. Ja już coś to coś takiego:
    Kod: asm
    Zaloguj się, aby zobaczyć kod

    0
  Szukaj w 5mln produktów