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

[ATmega8] [ATmega8][asembler] - Jak używać dwóch tablic dla wyświetlaczy LED?

KKobi 20 Wrz 2008 20:25 2696 14
  • #1 5554544
    KKobi
    Poziom 10  
    Posty: 29
    Czesc,
    Dosyc niedawno zainteresowalem sie uC.
    Pisze program ktory ma rosnąco pokazywac liczby na wyswietlaczu led.
    Mam 2 siedmiosegmentowe wyświetlacze. Liczby zawarlem w tablicy.
    Problem jest w tym ze probuje zrobic osobna tablice dla jednosci a osobną dla dziesiątek. Niestety tak to nie działa. Pomoze ktoś ?
    Oto problemowy kawałek kodu:
    
    ldi ZL, LOW(Liczba_LED*2)
    ldi ZH, HIGH(Liczba_LED*2)
    ldi XL, LOW(Liczba_LED*2)
    ldi XH, HIGH(Liczba_LED*2)
    ldi R23,0
    gora:
    lpm R1, X+
    out PORTC, R1
    ldi R22,0
    petla1:
    lpm R0, Z+
    out PORTD, R0
    rcall Czekaj250ms
    inc R22
    cpi R22, 10
    brlo petla1
    lpm R1, Z+
    inc R23
    cpi R23,10
    brlo gora
    
    liczba_LED:
    .db 0b11000000, 0b11111001 ;0, 1
    .db 0b10100100, 0b10110000 ;2, 3
    .db 0b10011001, 0b10010010 ;4, 5
    .db 0b10000010, 0b11111000 ;6, 7
    .db 0b10000000, 0b10010000 ;8, 9
    


    Przy X+ wyskakuje błąd. Dlaczego nie moge skorzystać z tych jakby 2 osobnych tablic ? Osobno dla Z i osobno dla X
    Dzięki za pomoc
  • #2 5554558
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    lpm działa tylko ze wskaźnikiem Z - musisz robić wymianę wskaźników (poczytaj o movw)
  • #3 5554670
    KKobi
    Poziom 10  
    Posty: 29
    Coś poczytałem, drugi wyświetlacz zaczął coś odpowiadać, ale kompletnie bez sensu, mozesz mi ten temat jaśniej opisać, co w tym
    przerobionym kodzie jest źle ?
    
    ldi ZL, LOW(Liczba_LED*2)
    ldi ZH, HIGH(Liczba_LED*2)
    ldi R23,0
    gora:
    ldi R22, 0
    movw R0, R30
    inc R30
    out PORTC, R0
    petla1:
    lpm R0, Z+
    out PORTD, R0
    rcall Czekaj250ms
    inc R22
    cpi R22, 10
    brlo petla1
    inc R23
    cpi R23,10
    
    brlo gora
    


    Dzieki...
  • #4 5554690
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    "Poczytaj o" a nie "zamień na"! "movw" wcale nie wczytuje elementu z pamięci programu. Stwierdzenie "wymiana wskaźników" jest chyba wystarczająco klarowne. Przechowujesz wskaźniki w rejestrach innych niż zh:zl, przed odczytem przenosisz odpowiedni wskaźnik do Z a po załadowaniu przenosisz go z powrotem. Jest jeszcze kilka innych sposobów, które opiszę w ostateczności.
  • #5 5554779
    KKobi
    Poziom 10  
    Posty: 29
    movw - kopiuje pare rejestrów...
    Samą idee rozumie, ale nie jestem na tyle wprawny w asemblerze, aby móc to zapisać :( Dopiero sie tego ucze...
  • #6 5556689
    ZbeeGin
    Poziom 39  
    Posty: 4327
    Pomógł: 602
    Ocena: 458
    Po prostu najpierw w tablicy poszukaj pierwszej liczby, zapamiętaj Z, "przewiń" Z na początek tablicy, znajduj drugą wartość, przywróć Z, i wróć do pierwszej liczby.

    A na przyszłość prosimy komentować swoje kody. Nie wiadomo czy to co napisałeś w kodzie jest zgodne z tym co chciałeś uzyskać i jakim tokiem myślenia się posługujesz.
  • #7 5557024
    KKobi
    Poziom 10  
    Posty: 29
    Dziekuje za zainteresowanie.
    Ja wiem jak to logicznie zrobić, ale asembler jest dla mnie nowym środowiskiem pracy.
    W jaki sposób zrealizować do "przewijanie" i "cofanie" ? Konkretnie jakie polecenia funkcje ? W C mozna sie odwolywac bezpośrednio do danej komórki tablicy np. Z[1] a tutaj jak to zrobić ? Jak na przykład potrzebuje 4 liczbe z tej tablicy "Liczba LED" to jak sie do niej odwołać ?
    Dzieki.
  • #8 5557261
    ZbeeGin
    Poziom 39  
    Posty: 4327
    Pomógł: 602
    Ocena: 458
    KKobi napisał:
    Ja wiem jak to logicznie zrobić, ale asembler jest dla mnie nowym środowiskiem pracy.

    Dlatego komentarze są jak najbardziej potrzebne.

    KKobi napisał:
    W jaki sposób zrealizować do "przewijanie" i "cofanie" ? Konkretnie jakie polecenia funkcje?

    "Przewijanie" już użyłeś. Po prostu wpisz do Z adres pierwszego elementu tablicy.
    "Zapamiętywanie" i "odtwarzanie" najlepiej przeprowadzić poprzez stos. Do tego służą polecenia PUSH, POP; a do tego ustawienie wskaźnika stosu SP na wartość zapisaną w specjalnej stałej RAMEND.

    Na przykład:

            ldi     r23, LOW(RAMEND)                ; ustaw stos sprzętowy
            out     SPL, r23
            ldi     r23, HIGH(RAMEND)
            out     SPH, r23
            
    licz:
            ldi     ZL, LOW(Liczba_LED * 2)         ; adres tablicy do Z
            ldi     ZH, HIGH(Liczba_LED * 2)
            clr     r23                             ; zeruj licznik dziesiątek
            
    gora:       
            lpm     r0, Z+                          ; pobierz dziesiątki
            out     PORTC, r0                       ; wyślij na port
            push    ZL                              ; zapamiętaj bieżący Z
            push    ZH
            ldi     ZL, LOW(Liczba_LED * 2)         ; przewiń na początek tablicy
            ldi     ZH, HIGH(Liczba_LED * 2)
            clr     r22                             ; zeruj licznik jedności
    
    _petla1: 
            lpm     r0, Z+                          ; pobierz cyfrę jedności
            out     PORTD, r0                       ; wystaw na port
            rcall   Czekaj250ms                     ; odczekaj
            inc     r22                             ; zwiększ licznik jedności
            cpi     r22, 10                         ; czy większy niż 10?
            brlo    _petla1                         ; jak nie to następna cyfra
            pop     ZH                              ; tak większe, przywracamy
            pop     ZL                              ; stare Z
            inc     r23                             ; zwiększamy licznik dziesiątek
            cpi     r23, 10                         ; czy większy niż 10?
            brlo    gora                            ; jak nie to licz dalej
            clr     r23                             ; inaczej zeruj
            rjmp    licz                            ; i od początku.
            
    liczba_LED:
            .db     0b11000000, 0b11111001          ; 0, 1 
            .db     0b10100100, 0b10110000          ; 2, 3 
            .db     0b10011001, 0b10010010          ; 4, 5 
            .db     0b10000010, 0b11111000          ; 6, 7 
            .db     0b10000000, 0b10010000          ; 8, 9


    KKobi napisał:
    Jak na przykład potrzebuje 4 liczbe z tej tablicy "Liczba LED" to jak sie do niej odwołać ?

    Dodaj do Z liczbę 3 a potem samo LPM:
            adiw    ZH:ZL, 3
            lpm     r0, Z

    Oczywiście Z musi wskazywać na początek tablicy.
  • #9 5559491
    KKobi
    Poziom 10  
    Posty: 29
    Wielkie dzieki :)
    Dokładnie o to mi chodziło.
    Widać, ze masz duzą wprawe, bez błędnie przejrzałeś mój kod.
    Mam jeszcze jedno pytanie:
    W jaki sposób zapisać dane do tablicy ? np. sprawdzam stan na porcie
    i zapisuje go do tablicy ?
    Co oznacza dokładne ".db" ? czy chodzi o liczby binarne ?jakie są tego alternatywy ?
    Jeszcze raz dziękuje za pomoc.
  • #10 5559558
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    KKobi może czas na jakąś książkę?
    .db to "data byte"
    Alternatywy np. .dw?

    Dane do tablicy? Oczywiście mówisz o RAMie, nie o FLASHu...
    No i oczywiście ładujesz adres do jakiegoś rej. indexowego, a potem używasz odpowiedniego rozkazu;-) np.st / std
  • #13 5561114
    KKobi
    Poziom 10  
    Posty: 29
    Zeby nie bylo...
    Czytam ile sie da o tym, ale literatura nie jest za bogata. Kupiłem
    książke Baranowskiego "atmeta w praktyce", ale nie jest to książka dla początkującego, a raczej kompendium wiedzy. Znalazłem tylko jednek kurs "od podstaw" ale są w nim tylko 3 lekcje.
    Jezeli mozecie polecic jakies dobre źródła... to chetnie je przeczytam...
    pozdrawiam
  • #14 5561175
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    Baranowski jest najlepszym PL źródłem na AVR. Ja się z niego nauczyłem.
    Jest to kompedium, ale dla początkujących tez jest git - ja zaczynałem z tą książką:)
  • #15 5561384
    ZbeeGin
    Poziom 39  
    Posty: 4327
    Pomógł: 602
    Ocena: 458
    Jak chcesz kupić coś od podstaw to polecam: Andrzej Pawluczuk (na forach jako gaweł) "Sztuka programowania mikrokontrolerów AVR". Są dwie części: Podstawy i Przykłady.

    Swoją drogą jest tam pewien brak, który chciałbym - a czasu ciągle mało - nieco uzupełnić takim małym eBookiem (w fazie projektowania spisu).

Podsumowanie tematu

✨ Dyskusja dotyczy programowania mikrokontrolera ATmega8 w asemblerze do sterowania dwoma siedmiosegmentowymi wyświetlaczami LED, wyświetlającymi rosnące liczby. Problemem było użycie dwóch osobnych tablic dla cyfr jedności i dziesiątek oraz próba odczytu danych z obu tablic za pomocą instrukcji lpm, która działa tylko ze wskaźnikiem Z. Rozwiązaniem jest zarządzanie wskaźnikami pamięci programu (rejestrami Z, X, Y) poprzez ich przełączanie i zapamiętywanie za pomocą stosu (instrukcje PUSH, POP) oraz kopiowanie wskaźników rejestrów (movw). Omówiono technikę "przewijania" i "cofania" wskaźnika Z, aby odwoływać się do różnych elementów tablicy w pamięci programu. Poruszono także kwestie zapisu danych do tablicy w pamięci RAM oraz znaczenie dyrektywy .db (data byte) do definiowania danych w pamięci programu. Wskazano na potrzebę komentowania kodu asemblerowego dla lepszego zrozumienia. W dyskusji polecono literaturę do nauki programowania AVR, w tym książki Baranowskiego oraz Andrzeja Pawluczuka, jako wartościowe źródła wiedzy dla początkujących i zaawansowanych.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA