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

Assembler - odczyt danych z tablicy

ziomalesko 18 Sty 2012 17:48 6061 18
  • #1 10415111
    ziomalesko
    Poziom 11  
    Witam serdecznie.

    Wie ktoś może w jaki sposób odczytuje się dane z tablicy w assemblerze?

    Oto fragment kodu:

    Atmega8
    Kompilator AVR studio 4.19

    Kod: text
    Zaloguj się, aby zobaczyć kod


    W podanym fragmencie kodu button1 odczytuje tylko pierwszy element tablicy table i zapisuje go do rejestru R20, zaś button2 czwarty element (również zapisuje go do R20).

    Założenie jest takie, że button ma odczytywać kolejno (rosnąco) elementy tablicy i zapisywać je do rejestru, zaś button2 malejąco kolejno od aktualnie skopiowanego do rejestru elementu tablicy
  • #3 10415309
    ziomalesko
    Poziom 11  
    Ach tak, procesor to Atmega8
  • #4 10415502
    myszaF2
    Poziom 10  
    Dla mikrokontrolerów Atmel AVR wygląda to następująco:


    buton1:
    ldi ZH,high(2*tablica)
    ldi ZL,low(2*tablica) ;ładownie tablicy do pamięci programu
    adiw ZL,1 ;dodawanie do adresu elementu tablicy
    lpm ;odczyt z tablicy do r0 - zawsze tam znajdzie się dana
    mov temp,r0 ;kopiowanie danej do rejestru ogólnego użytku
    sbiw ZL,1 ;odejmowanie od adresu elementu tablicy
    lpm ;odczyt z tablicy do r0
    mov temp,r0 ;kopiowanie danej do rejestru ogólnego użytku
    rjmp main ;powrót
    tablica:
    .db 1,2,3,4,5,6,7,8,9

    Domyślnym adresem tablicy będzie adres 0 czyli u nas element "1".
    adiw doda do adresu 0 podaną wartość u nas "1" czyli odczyta element "2".
    sbiw odejmie adres elementu tablicy podana wartość u nas "1" czyli odczyta elemet "1".
    Jeżeli mamy tylko jedną tablicę wystarczy ją tylko raz załadować np. na początku programu.

    Pozdrawiam!

    Dodano po 1 [minuty]:

    Przepraszam ale trochę ładniej to wyglądało podczas pisania po znaku ;są komentarze.
  • #5 10417027
    excray
    Poziom 41  
    myszaF2 napisał:
    lpm ;odczyt z tablicy do r0 - zawsze tam znajdzie się dana

    myszaF2 napisał:
    lpm ;odczyt z tablicy do r0
    mov temp,r0 ;kopiowanie danej do rejestru ogólnego użytku

    Mylisz się. Rozkazem lpm można wczytać dane z flash do dowolnego rejestru:
    lpm temp,Z
    albo
    lpm temp,Z+ jeśli czytamy po kolei kolejne elementy tablicy
    Poza tym lpm działa dla tablicy w pamięci flash a często dane są w pamięci RAM a wtedy stosuje się cały szereg rozkazów ld, ldd i lds oraz analogicznie do zapisu st, std, sts

    Assembler - odczyt danych z tablicy
  • #6 10417085
    Konto nie istnieje
    Konto nie istnieje  
  • #7 10417226
    excray
    Poziom 41  
    Saabotaz napisał:
    Z tym LPM to różnie bywa. Samo LPM bez parametru zadziała na pewno i kompilator też przyjmie. Nowe LPM z dowolnym rejestrem to dobra sprawa ale ja z tego nie korzystam, nie chcę niespodzianek.

    ??????? OMG!!! Sugerujesz że Atmel tak sobie powrzucał rozkazy na listę nie sprawdzając ich działania? Zalecam na wszelki wypadek nie korzystać z większej liczby rozkazów bo też mogą sprawiać niespodzianki. Polecam używanie głównie NOP. Zazwyczaj nie sprawia niespodzianek, w miarę stabilny rozkaz. Masz może jeszcze uwagi co do rejestrów? Których nie używasz bo są nieobliczalne?
  • #8 10417278
    Konto nie istnieje
    Konto nie istnieje  
  • #9 10417312
    excray
    Poziom 41  
    Saabotaz napisał:
    excray - no tak, widać żeś ze wsi, wypij szklankę zimnej wody to może ochłoniesz. LPM z parametrem kiedyś nie było, teraz jest. Nie wiadomo z jakiego kompilatora korzysta programista, stare wersje mogą przyjmować tylko samo LPM. Pomyśl trochę zanim następnym razem znów wylejesz na kogoś swoje żale.

    Ciekawe, ciekawe :-) Piękne bajki opowiadasz. A ta zajawka ze wsią - majstersztyk Ale muszę ci powiedzieć że LPM w takiej formie ZAWSZE było w tym procesorze, nic tu nigdy się nie zmieniło więc twoja historia musiała Ci się przyśnić. Trzeba tylko pamiętać o ograniczeniach w obszarze działania funkcji LPM i używać jej z głową a przede wszystkim czytać datasheet.
  • #10 10419420
    ziomalesko
    Poziom 11  
    Zrobiłem coś takiego:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Jednak nie przyniosło to zamierzonego rezultatu.

    Wcześniej (gdy odczytywało pierwszy i czwarty element tablicy)
    po przyciśnięciu pierwszego przycisku dioda świeciła mocniej, drugiego słabiej, ale świeciła cały czas.

    Teraz jest tak, że po przyciśnięciu przycisku dioda czasem tylko mignie.

    W każdym razie wszystko jest na dobrej drodze, raz miga jaśniej, raz ciemniej.
    Nie wiem tylko dlaczego nie zawsze się zaświeci i dlaczego gaśnie...
  • #11 10419805
    myszaF2
    Poziom 10  
    Pięknie sobie na wzajem "ciśniecie". A kolega zadający pytanie nadal nie uzyskał odpowiedzi...Czyli standardowo...
    Mi komenda lpm temp,Z zgłasza ostrzerzenie(komenda nie wspierana w tym procesorze)
    Asembler ma bardzo dużo tzw. "knyfów". Długo już w nim piszę i nie jeden program nie zadziałał.
    Ziomalesko zrób proszę tak jak napisałem i na pewno zadziała. Polecam Tobie środowisko VMLAB. Masz tam pełną symulację programu wraz z możliwością "dołączenia" różnych elementów elektronicznych.

    button1:
    adiw ZL,1
    lpm
    mov temp,r0
    rjmp main

    button2:
    sbiw ZL,1
    lpm
    mov temp,r0
    rjmp main

    table:
    .db elementy po przecinkach

    Rozumiem ,że na koncu button2 dajesz komendę powrotu w przeciwnym razie procesor wykona następną kolejną operację a jesli jej nie ma "wyskoczy" w bliżej nie znany obszar pamięci. Na szczęscie jest Wathdog który od razu wykona reset i program wykona sie od początku.
    Możesz napisać co chcesz osiągnąć tym odczytem z tablicy. Jeżeli po odczycie prównujesz tylko dana z tablicy do np. stałej nie musisz kopiować jej do temp.
    Jak nie dasz rady wklej cały kod.
    Pozdrawiam!
  • #12 10420148
    ziomalesko
    Poziom 11  
    Teraz już całkiem nie działa... :/

    Muszę przyznać, że nie czuję się najlepiej w asemblerze.
    Mam nadzieję, że nie będę musiał już więcej nic w nim pisać.

    Wklejam kod:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    myszaF2, dziękuję, że zainteresowałeś się moim problemem.

    Lepiej będzie jeśli podczas wklejania kodu użyjesz pełnej edycji i użyjesz znaczników SYNTAX - kod będzie o wiele czytelniejszy. ;)

    Pozdrawiam.
  • #13 10420275
    myszaF2
    Poziom 10  
    Procesor jest "trochę" szybszy od człowieka a Ty nie uwzględniłeś drgań styków przycisku oraz nie czekasz na jego zwolnienie. Co program ma zrobić z pobraną daną z tablicy?Nie zdefiniowałeś przerwania 0x18. Najlepiej po nie używanych wektorach przerwań dac RETI.Po co przerwania z TIMERA?

    Dodano po 1 [godziny] 44 [minuty]:

    A oto kod działającego programu wybacz za brak komentarzy ale nie mam już na nie czasu.
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Dodano po 1 [minuty]:

    Asembler jest kochany:)
  • #14 10420951
    excray
    Poziom 41  
    myszaF2 napisał:
    Mi komenda lpm temp,Z zgłasza ostrzerzenie(komenda nie wspierana w tym procesorze)
    Asembler ma bardzo dużo tzw. "knyfów". Długo już w nim piszę i nie jeden program nie zadziałał.

    Czy oby na pewno wszyscy mówimy o ATMEGA8 bo ja odnoszę wrażenie że chyba każdy tutaj pisze pod inny procesor. Stos źle skonfigurowany. Chyba że kolega kompiluje pod zupełnie inny procesor? Bo takie właśnie odnoszę wrażenie po zacytowanej odpowiedzi. Poza tym jeśli kompilator pisze takie głupoty że LPM r16,Z+ nie jest wspierane przez ATMEGA8 to powinieneś zmienić kompilator.
    myszaF2 napisał:
    Nie zdefiniowałeś przerwania 0x18

    To nie jest żadne przerwanie tylko adres etykiety "start"

    Dodano po 7 [minuty]:

    myszaF2 napisał:
    A oto kod działającego programu wybacz za brak komentarzy ale nie mam już na nie czasu.
    ....
    Dodano po 1 [minuty]:

    Asembler jest kochany:)

    Gdzie jest definicja procesora?
    Co to jest?
    Cytat:
    clr adr
    Ten procesor nie ma żadnego rejestru adr a Ty nie zdefiniowałeś żadnego z taką nazwą. Nie wiem jak tobie ale mi ten kod nie działa. Jeśli Ci się skompilował to zdecydowanie musisz zmienić kompilator. Po co wpisujesz te wszystkie powroty z przerwań skoro nie inicjujesz żadnych przerwań?

    Dodano po 7 [minuty]:

    myszaF2 napisał:
    ldi temp,0b11111001
    out TCCR2,temp

    Pomijając to że w taki sposób się nie pisze, powiedz mi po co ustawiasz FOC2 i COM20? Zajrzyj do datasheet i zobacz co w ten sposób uaktywniłeś.

    Dodano po 2 [minuty]:

    myszaF2 napisał:
    out TCNT2,temp
    Jak wyżej. Wytłumacz mi co chciałeś osiągnąć wykonując ten rozkaz. Albo raczej po co.

    Dodano po 48 [minuty]:

    ziomalesko poprawiłem Twój kod:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    PINB1 - tutaj podpinasz przycisk zwierający do masy
    PINB3 - wyjście PWM
    Jeśli zmieniasz ilość elementów w tablicy musisz zmienić wartość r17 w procedurze tabstart
    Zwróc uwagę na taktowanie - wewnętrzny oscylator RC 1MHz
  • #15 10421843
    ziomalesko
    Poziom 11  
    Wszystko pięknie, ładnie, ale żaden z programów nie działa...
    Program [b]excray[\b]'a, się kompiluje, ale:
    nie widzę nigdzie wyjścia OCR1A (PB1), na które jest podawany sygnał wyjściowy PWM'a.
    Na wyjście to podawany jest stan niski (ustawiony bit COM1A1).
    Dodam tylko, że chodzi o PWM w trybie Phase Correct.

    W moim programie wszystko jest ok, poza odczytem danych z tablicy.
    Wyjście PWM to rejestr OCR1A (PB1, 15), przyciski są na pinach PC1, PC2 (24, 25)

    Płytka jest już gotowa, więc rejestry powinny zostać bez zmian.
  • #16 10423364
    excray
    Poziom 41  
    ziomalesko napisał:
    Wszystko pięknie, ładnie, ale żaden z programów nie działa...
    Program excray'a, się kompiluje, ale:
    nie widzę nigdzie wyjścia OCR1A (PB1), na które jest podawany sygnał wyjściowy PWM'a.
    Na wyjście to podawany jest stan niski (ustawiony bit COM1A1).
    Dodam tylko, że chodzi o PWM w trybie Phase Correct.

    W moim programie wszystko jest ok, poza odczytem danych z tablicy.
    Wyjście PWM to rejestr OCR1A (PB1, 15), przyciski są na pinach PC1, PC2 (24, 25)

    Mi działa. I w teorii i w praktyce. Skoro już zrobiłeś na innych pinach a nie raczyłeś wcześniej tego powiedzieć to sam sobie przepisz program na te inne piny i timer 1. Ogólną ideę już masz.
  • #17 10439242
    myszaF2
    Poziom 10  
    Kod: text
    Zaloguj się, aby zobaczyć kod

    PC1 PWM+
    PC2 PWM-
    PB3 PWM OUT

    Oto caly kod z VMLAB stąd inaczej .include. Nie napisałem tego wcześniej bo uznałem, że to nie jest możliwe żeby ktoś się zastanawiał co tam wpisać ale ok. Oba kody działają. A co do wpisywania do rejestrów Timera w ten sposób np. 0b11101101 to nie jest tak, że się nie robi. Każdy pisze po swojemu i mi tak jest łatwiej. Mniejsza z tym nie mam zamiaru tu sie kłucic co jest lepsze a co gorsze oba kody działają więc kolego wybieraj który chcesz. Pozdrawiam!
  • #18 10439967
    ziomalesko
    Poziom 11  
    Dzięki panowie za starania.
  • #19 10443496
    asembler
    Poziom 32  
    excray napisał:
    Saabotaz napisał:
    excray - no tak, widać żeś ze wsi, wypij szklankę zimnej wody to może ochłoniesz. LPM z parametrem kiedyś nie było, teraz jest. Nie wiadomo z jakiego kompilatora korzysta programista, stare wersje mogą przyjmować tylko samo LPM. Pomyśl trochę zanim następnym razem znów wylejesz na kogoś swoje żale.

    Ciekawe, ciekawe :-) Piękne bajki opowiadasz. A ta zajawka ze wsią - majstersztyk Ale muszę ci powiedzieć że LPM w takiej formie ZAWSZE było w tym procesorze, nic tu nigdy się nie zmieniło więc twoja historia musiała Ci się przyśnić. Trzeba tylko pamiętać o ograniczeniach w obszarze działania funkcji LPM i używać jej z głową a przede wszystkim czytać datasheet.


    excray ma rację
REKLAMA