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

licznik ATmega8 asembler - coś nie tak z tym programem

as124 09 Maj 2007 15:09 1932 6
REKLAMA
  • #1 3865825
    as124
    Poziom 14  
    Posty: 145
    Ocena: 15
    Przepraszam za zakładanie nowego wątku w temacie tyle razy poruszanym na forum ale właśnie program oparty na wiedzy z forum mi nie działa. Ogólnie układ powinien co 1sek zwiększać wartość na linijce diodowej podłączonej do portu B i w symulacjach na WINAVR to właściwie działa jednak, gdy wgrałem program do kości ciągle obserwuje świecenie pierwszej diody:( Może ktoś podpowie co robie źle?

    INCLUDE "plik_definicji.txt"

    ;----------SEGMENT DANYCH--------------------------------
    .DSEG
    .ORG 0x60

    ;----------WEKTORY PRZERWAN------------------------------
    .CSEG
    .ORG 0 ; wektor przerwania inicjalizacji
    rjmp Reset ; skok do procedury inicjalizacji

    .ORG OC1Aaddr
    rjmp zwieksz

    ;----------SEGMENT PROGRAMU------------------------------

    Main:
    jmp Main

    ;----------SEGMENT PRZERWAN------------------------------

    ///////////////////////////////////przerwanie inicjalizujace
    Reset:
    ; ustawienie wskaznika stosu
    ldi R16, high(RAMEND)
    ldi R17, low(RAMEND)
    out SPH, R16
    out SPL, R17

    ; port B jako wyjscie
    ldi R16, 0xFF
    out DDRB, R16

    ; wlacznie licznika
    ldi R16, 0b00000000 ; tryb ctc czestotoliwosc 1MHz
    ldi R17, 0b00001010
    out TCCR1A, R16
    out TCCR1B, R17

    ldi R16, TIMSK ; wlaczenie przerwania dla wyrowania ocr1a i licznika
    ori R16, 1<<TOIE1
    out TIMSK, R16

    ldi R16, 0b00010000 ; wpisanie 10000 czyli przerwanie co 10ms
    ldi R17, 0b00100111
    out OCR1AH, R16
    out OCR1AL, R17

    ldi R16, 0x00 ; wyczyszczenie r16

    ldi R17, 0b00000001 ;zapalenie 1 diody
    out PORTB, R17

    sei; zezwolenie globalne na int
    jmp Main


    zwieksz:

    inc R20

    cpi R20, 100 ; jesli r20=100 (czyli minela 1sek.)
    breq zmien_diody ;to skocz do zmien diody jesli nie to skocz do koniec_int_licznik
    jmp koniec_int_licznik

    zmien_diody: ; wyzeruj r20 i zwieksz wartosc na linijce diodowej
    ldi R20, 0
    inc R17
    out PORTB, R17

    koniec_int_licznik:
    reti
  • REKLAMA
  • #2 3865868
    Dr_DEAD
    Poziom 28  
    Posty: 829
    Pomógł: 126
    Ocena: 3
    Pierwszy raz widzę assemplera od AVR więc mogę się mylić, ale czy nie brakuje ci ORG'a?
    as124 napisał:


    ;----------WEKTORY PRZERWAN------------------------------
    .CSEG
    .ORG 0 ; wektor przerwania inicjalizacji
    rjmp Reset ; skok do procedury inicjalizacji

    .ORG OC1Aaddr
    rjmp zwieksz

    ;----------SEGMENT PROGRAMU------------------------------
    .ORG Coś tam Cośtam <- tu dopisałem.

    Main:
    jmp Main

    ;----------SEGMENT PRZERWAN------------------------------

    Bo na mój rozum to resztę programu miałeś w nieodpowiedniej części Flasha.
  • REKLAMA
  • #3 3865906
    as124
    Poziom 14  
    Posty: 145
    Ocena: 15
    Spróbowałem tak:

    CSEG
    .ORG 0 ; wektor przerwania inicjalizacji
    rjmp Reset ; skok do procedury inicjalizacji

    .ORG OC1Aaddr
    rjmp zwieksz

    ;----------SEGMENT PROGRAMU------------------------------
    .ORG Coś tam Cośtam <- tu dopisałem. (tylko zamiast cos tam dałem
    .ORG 0x013 tak sobie)

    Main:
    jmp Main

    ;----------SEGMENT PRZERWAN------------------------------




    ... I zgodnie z tym co przewidywałem zresztą:( nic to nie daje.:( Ogólnie to bez tego .ORG cos tam program itak wykona najpierw Reset a potem przejdzie do Main i tam zostaje w pętli

    Main:
    jmp Main

    doświadczenie mi pokazało wcześniej że takie coś działa więc tutaj chyba też. Ale dziękuję za próbę i może jakiś inny pomysł bo ten niestety nic nie wnosi:(.
  • REKLAMA
  • #4 3865922
    Dr_DEAD
    Poziom 28  
    Posty: 829
    Pomógł: 126
    Ocena: 3
    A odblokowałeś globalne przerwania, bo chyba coś takiego funkcjonuje w AVR.
    dopisane:
    Znalazłem: SEI Global Interrupt Enable
    dopisane:
    Przeoczyłem SEI jest w twoim programie.
    dopisane:
    Może masz WatchDoga włączonego i sie procek resetuje.
  • #5 3865993
    as124
    Poziom 14  
    Posty: 145
    Ocena: 15
    No watchdog nie jest włączony więc nie powinien resetować procka:| Na wszelki wypadek spróbowałem go resetować w mainie czyli mam tak:

    Main:
    wdr ;
    jmp Main
    Ale to też nic nie wnosi (zgodnie zresztą z przewidywaniami:(. ) Zapomniałem dodać a to też może budzić pytania kość pracuje na 8MHz a preskaler ustawiam na 8

    ldi R16, 0b00000000 ; tryb ctc czestotoliwosc 1MHz
    ldi R17, 0b00001010
    out TCCR1A, R16
    out TCCR1B, R17

    dlatego w komentarzu jest "tryb ctc czestotoliwosc 1MHz" czyli licznik inkrementuje sie z czestotliwoscia 1MHz zlicza do 10000 wiec przerwanie mam co 10ms. 100 przerwań daje mi zmiane na porcie B (no właśnie powinno ale tak nie jest:( ).
  • REKLAMA
  • #7 3866751
    as124
    Poziom 14  
    Posty: 145
    Ocena: 15
    Rzeczywiście ma być in R16,TIMSK zamiast ldi - poprawiłem. Jakiś czeski błąd mi się zrobił. No ale niestety ciągle świeci mi tylko ta jedna diodka:(.

    Dodano po 10 [minuty]:

    Wreszcie znalazłem dobre rozwiązanie. Błąd był w tym miejscu:

    in R16, TIMSK ; wlaczenie przerwania dla wyrowania ocr1a i licznika
    ori R16, 1<<TOIE1

    Otórz TOIE1 włącza przerwanie od licznika ale chyba tylko przy przepełnieniu natomiast powinno być:

    in R16, TIMSK ; wlaczenie przerwania dla wyrowania ocr1a i licznika
    ori R16, 1<<OCIE1A

    Czyli przerwanie włącza się w momencie zrównania z OCR1A. Przynajmniej tak to rozumiem (niestety mój angielski jest słaby). Przynajmniej tak linijka mruga inna sprawa czy aby napewno z częstotliwością 1Hz ale to jeszcze sprawdzę.

    [

Podsumowanie tematu

✨ Dyskusja dotyczy problemu z działaniem programu asemblerowego na mikrokontrolerze ATmega8, który ma za zadanie inkrementować wartość na diodowej linii portu B co sekundę. Program działa poprawnie w symulacji WINAVR, jednak na rzeczywistym układzie świeci tylko pierwsza dioda. Wskazano potencjalne błędy, takie jak brak odpowiedniego ustawienia segmentów pamięci (.ORG) oraz nieprawidłowe włączenie przerwań. Ostatecznie rozwiązaniem okazała się poprawna konfiguracja rejestru TIMSK – zamiast włączać przerwanie od przepełnienia licznika (TOIE1), należy włączyć przerwanie od porównania z rejestrem OCR1A (OCIE1A). Dodatkowo omówiono ustawienia trybu CTC i preskalera dla timera, a także wykluczono problem z włączonym Watchdogiem. Poprawne włączenie przerwań i konfiguracja timerów pozwoliły na prawidłowe działanie programu.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA