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 uzyskać 1s opóźnienia na liczniku T0 w asemblerze? Kwarc 20MHz, cykl 0,8us

davciu 21 Wrz 2005 21:21 1221 2
REKLAMA
  • #1 1838100
    davciu
    Poziom 11  
    Posty: 73
    Pomógł: 1
    Ocena: 4
    Jestem początkujący. Czy ktoś mógłby mi opisać jak zrobić opóźnienie na liczniku T0 w asemblerze. Ważne są ustawienia TMOD i TCON ale co dalej. Chce uzyskać opóźnienie około 1s (jak wywołać przerwanie od licznika i jak je realizowac aby trwało 1s) ? Kwarc 20MHz, cykl maszynowy trwa 0,8us.
  • REKLAMA
  • #2 1854504
    coberr
    Poziom 20  
    Posty: 845
    Pomógł: 21
    Ocena: 434
    witam.

    Ten post powinien znależć się raczej w dziale mikrokontrolery - a nie tutaj
    tam szybciej uzyskasz odpowiedz na to pytanie.

    Jezeli chodzi o licznik to wyglada to tak:

    timer zgłasza przerwanie w moencie przepełnienia (przejście z FFFFh na 0000h )
    najlepiej zeby pracował jako 16bit w trybie zliczania imp. wewn zegara.

    nie wiem czy dobrze obliczyłem - ale o ile sie nie walnąłem - to przy takim kwarcu cykl wynosi 0,6uS

    normalnie licznik będzie zliczał od 0 do 65535 - co do jakies 39ms (pi x oko)

    jednak - aby nie mieszac sobie w wynikach przyjmujemy ładowanie go jakąś wartością początkową po kazdym przerwaniu
    ten kwarc jest nieciekawy - lepiej bybyło zastosować 24MHz :)
    byłoby 500ns a nie 600 ale jak juz mamy 600 - to obliczamy sobie zawartość licznika dla czasu równego 20ms (przykładowo) i otrzymujemy TH=33333 - a zatem po odjęciu tego od pełnego wyniku otrzymujemy wartośc pocz. równą 32202 - i to jest nasza pocz. wartość licznika ktora ma byc wpisana przy obsłudze kazdego przerwania.
    licznik liczy wtedy od 32202 do 65535 i w przyblizeniu co 20ms zgłosi przerwanie.

    następnie deklarujemy sobie jakiś rejestr , ktory będziemy testowali i inkrementowali przy kazdym przerwniu - np R0.

    jezeli przerwanie jest zgłaszane co 20ms -to w przeciągu sekundy program obsł. przerwania powinien wykonac sie 50 razy.

    a zatem-
    program obsługi przerwania powinien:

    -wykasować odpowiednie znaczniki przerwań,
    -załadować do TH0,TL0 odpowiednia wartość.
    - przetestować czy r0=50
    - jesli tak - ustawiany jest jakis znacznik, ktory testowany jest przez program głowny (po wyjsciu z pr. obsł.przerw.)
    (dodatkowo r0 zostaje ustawiony na 0 - aby od pocz. odliczac czas)
    jezeli nie - r0 jest inkrementowany o 1 i następuje wyjscie z obsł. przerwania.


    znacznik ten powinien byc kasowany przez program główny (najlepiej )

    tym sposobem (chyba jnajprostszym) otrzymujemy mozliwośc testowania - czy minęła 1 sek. czy nie.

    jest to dosc ogólny schemat - ale myslke ze zrozumiały.

    jesli gdzies walnąłem byka - prosze mnie poprawić (bo pisze kompletnie z pamieci i pewnych rzeczy poprostu mogę nie pamietac :) )
  • #3 1870925
    nadmiszcz
    Poziom 16  
    Posty: 126
    Pomógł: 15
    Ocena: 4
    jeżeli mogę sie dołączyć do tej dyskusji to chciałbym zaznaczyć, że podany przez Cobbera sposób najlepiej zrealizować za pomocą licznika T2, ze względu na możliwość ustawienia tego licznika w trybie autoładowania na całych 16 bitach; w pozostałych (T0 i T1) ta metoda będzie niedokładna - do okresu między przerwaniami trzeba będzie doliczyć czas wykonywania instrukcji w progr. przerw. aż do momentu wpisania wartości do TL i TH .
    Czyli od tych 33333 cykli trzeba by odjąc 2cykle na wejście w przerwanie i odpowiednią ilość instrukcji aż do MOV TL,#... i TH.
    Ten problem gdzieś już był opisany na forum (chyba ktoś pytał o odmierzanie 1 minuty w 89s51).
    Natomiast liczniki T0 i T1 w autoładowaniu pracują jako 8bit i dla nich (przy 12MHz) mogło by to tak wyglądać:

    w C:
    unsigned int licz;

    void blablabla (void) interrupt 1
    {
    if (++licz==4000) {
    F0=1;
    licz=0;}
    }

    w asm:

    przerwanie: djnz r0,aaa
    mov r0,#100
    djnz r1,aaa
    mov r1,#100
    setb F0
    aaa: reti

    program: mov TCON,#16 ;licznik T0
    mov TMOD,#2 ;tryb 2 (autoladowanie)

    mov TL0,#156 ;odmierza 100 cykli
    mov TH0,#156 ; 100us

    mov r0,#100
    mov r1,#100
    setb ET0
    setb EA

    dokładnie co 1 sek ustawiana jest flaga F0 w PSW.
    kasowanie go, jak napisał kolega np

    JBC F0,sekunda
    ...
    sekunda: ....

    jednak ta metoda nieco obciąża procesor - program główny będzie wykonywany trochę wolniej.
    Powyższe procedury są dla kwarcu 12MHz, dla innych trzeba skorygować wartości porównań.
    prog dla licznika T2 nie napiszę bo może mieć różnie rejestry, zależnie od uC.
REKLAMA