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

Jak podzielić wynik ADC przez 400 w asm dla AVR mega8?

bua 13 Mar 2007 10:52 1983 7
REKLAMA
  • #1 3673551
    bua
    Poziom 12  
    Posty: 81
    Pomógł: 1
    Już kompletnie zgłupiałem...
    Mam ustawiony preskaler na 32, internal Vref (2.56V) czyli wynik zapisany
    w ADC trzeba podzielić przez 400 żeby otrzymać przetworzoną wielkość.

    No i teraz nie rozumiem jak to zrobić w asmie... dopiero zaczynam pisałem już coś w C...
    Operator "/" daje w wyniku część całkowitą...
    Może trzeba sobie to jakoś wirtualnie zapamiętać gdzie jest ten przecinek, tak jak w DSP
    Chciałbym wyświetlić wynik na LCD...więc ustalam(teoretycznie) że mam jedno miejsce na część całkowitą |x| (tutaj 3 wartości 1,2 lub 0) potem "." no i 4 miejsca po przecinku |xxxx| i mam sobie analizować jeśli ADCH = 0x02 to na i ADCL>= 0xf0 to napewno liczba całkowita będzie 2 czyli wynik dla tego co napisałem 2,0160[V]...

    czy to dobre podejście czy można to jakoś prościej zrobić
    Prosze o pomoc bo już nie widze nawet prostych błedów..
  • REKLAMA
  • #2 3673616
    marek_Łódź
    Poziom 36  
    Posty: 3103
    Pomógł: 208
    Ocena: 66
    bua napisał:
    Już kompletnie zgłupiałem...
    Ja też ;-)
    bua napisał:
    Mam ustawiony preskaler na 32, internal Vref (2.56V) czyli wynik zapisany w ADC trzeba podzielić przez 400 żeby otrzymać przetworzoną wielkość.
    Wynik odczytany z przetwornika trzeba podzielić przez 4 (jednostką będzie 0.01V) i przekonwertować go do BCD->STRING po czym wysłać na wyświetlacz uwzględniając odpowiednią pozycję kropki dziesiętnej.

    2,56x(0x2f0/0x400)=1.8800V
    2,56x(0x2f1/0x400)=1.8825V
    2,56x(0x2f2/0x400)=1.8850V
    2,56x(0x2f3/0x400)=1.8875V ...itd

    czyli inaczej mówiąc osiem najstarszych bitów wyniku po konwersji do BCD da Ci 3 starsze cyfry wyniku, natomiast liczba utworzona z dwóch najmłodszych bitów - dwie najmłodsze cyfry wyniku - dziesięciotysięczne wolta (00=="00", 01=="0.25", 02=="50", ", 03=="75")
  • REKLAMA
  • #3 3674443
    Samuraj
    Poziom 35  
    Posty: 2792
    Pomógł: 286
    Ocena: 619
    A nie prościej mnożyć niż dzielić i to jeszcze z przecinkiem.
    aby otrzymać 18800 = 0x4970h / 0x02F0h = 0x19h
    I teraz:

    0x02F0h x 0x19h = 0x4970h = 18800
    0x02F1h x 0x19h = 0x4989h = 18825
    0x02F2h x 0x19h = 0x49A2h = 18850
    0x02F3h x 0x19h = 0x49BBh = 18875

    Lepiej operować na liczbach całkowitych, szczególnie w C. Przecinek wyświetlić to nie problem. Tym bardziej że zawsze jest na trzeciej pozycji od lewej.
  • REKLAMA
  • #4 3674886
    marek_Łódź
    Poziom 36  
    Posty: 3103
    Pomógł: 208
    Ocena: 66
    Akurat w tym, konkretnym przypadku dzielenie przez 4 polega na pobraniu starszego bajtu (dokładnie 1 cykl maszynowy), a resztę z dzielenia mamy w dwóch pozostałych bitach, co z pewnością jest prostsze od przedstawionego wyżej mnożenia. Oczywiście cały czas mówimy tu o zmiennych stałopozycyjnych. Korzystając z tablic konwersji całe wygenerowanie łańcucha tekstowego, wysyłanego na LCD, powinno się zamknąć w kilku-kilkunastu cyklach maszynowych.
  • REKLAMA
  • #5 3676419
    bua
    Poziom 12  
    Posty: 81
    Pomógł: 1
    Dziękuje za naprowadzenie mnie na właściwą ścieżke....:)

    Cytat:
    Korzystając z tablic konwersji całe wygenerowanie łańcucha tekstowego, wysyłanego na LCD, powinno się zamknąć w kilku-kilkunastu cyklach maszynowych.


    Zaciekawiło mnie to bo w sumie wymiśliłem sobie taki algorytm:

    np. dec = 195 dla starszego bajtu ...
    195/10-> 19 zapisujemy do rejestru....
    19*10 = 190 ....195-190=5.... i mamy trzecią liczbe
    190/100 = 1.....1*100=100....190-100=90.....

    itd..
    Wymyśliłem sobie to ze względu na brak doświadczenia, ale tutaj napotkałem małego zonka, bo ni cholery nie wiem jak wykożystać znaczek "/" .....
    może atmega8 nie obsługuje takiego dzielenia....w sumie naczytałem sie helpa dla mega8 i nic nie znalazłem...
    dlatego jeżeli mógłbyś wyjaśnić co to są te tablice konwersji, i jak to można zrobić w kilku funcjach...:)

    ps. z desperacji używałem wszystkich ld, ldi, mov, na pałe ze wszystkimi kombinacjami....żałosne ale prawdziwe...:(

    Najzabawniejsze że 2x16 i UART w C poszedł jak z płatka w kilka godzin...
    Jak tak dalej pójdzie to asm pujdzie w odstawke....:(
    więc proszę miłośników asm do tego aby przytrzymali potencjalnego zwolennika na duchu....:)

    .
    .
    .
    .
    znalazłem coś takiego tutaj:
    https://www.elektroda.pl/rtvforum/topic133117.html
    plus to co znalazłem jeszcze na stronie atmela odnośnie dzielenia i mnożenia....
    jutro sobie to poczytam i może coś z tego wyjdzie...(jakbym miał przeczytać te wszystkie datasheety i instrukcje i kursy i jeszcze bóg wie co to by mi nie starczyło życia żeby cokolwiek zrobić....)
  • #6 3679911
    Ch.M.
    Poziom 27  
    Posty: 1009
    Pomógł: 62
    Ocena: 15
    Witaj
    Zapoznaj sie z komendami ror oraz lsr i wszystko stanie się jasne :)
    Pozdrawiam
  • #7 5226205
    MEGA88
    Poziom 11  
    Posty: 7
    spodobał mi sie pomysł samuraja, tylko jak zapisac tak duze wartości w 8 bitowych rejestrach programując w asamblerze?
  • #8 5227984
    Ch.M.
    Poziom 27  
    Posty: 1009
    Pomógł: 62
    Ocena: 15
    tak czy siak wynik 10bitowej konwersji ADC to dwa bajty więc nie bardzo rozumiem o co pytasz ?

Podsumowanie tematu

✨ Dyskusja dotyczy problemu dzielenia wyniku 10-bitowego przetwornika ADC w mikrokontrolerze AVR ATmega8 przez 400 w asemblerze. Użytkownik chce przeliczyć odczyt ADC z preskalerem 32 i wewnętrznym napięciem odniesienia 2,56 V na wartość napięcia z dokładnością do czterech miejsc po przecinku i wyświetlić ją na LCD. Wskazano, że dzielenie przez 400 można uprościć do dzielenia przez 4, a wynik przeliczyć na format BCD, co ułatwia konwersję do tekstu i wyświetlanie. Zaproponowano operacje na liczbach całkowitych zamiast dzielenia zmiennoprzecinkowego, np. mnożenie przez stałą, oraz wykorzystanie przesunięć bitowych (ror, lsr) do szybkiego dzielenia przez 4. Omówiono też metodę rozkładu liczby na cyfry dziesiętne przez dzielenie i odejmowanie, co można zrealizować w asemblerze za pomocą tablic konwersji. Podkreślono, że wynik ADC zajmuje dwa bajty, co pozwala na operacje na 16-bitowych wartościach w 8-bitowych rejestrach. Wskazówki dotyczące asemblera i konwersji ułatwiają implementację wyświetlania wartości ADC na LCD bez użycia dzielenia zmiennoprzecinkowego.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA