Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

dsm51,timery,Tryb 1

tazit 20 Kwi 2009 13:09 3109 17
  • #1 20 Kwi 2009 13:09
    tazit
    Poziom 9  

    Witam.Chciałbym prosić o wytłumaczenie pewnej sprawy.Otóż mam za zadanie sterować wyświetlaczem 7-segmentowym za pomocą timerów.
    Pragnę dokładnie dowiedzieć się jak działają timery(na razie sprawy wyświetlacza nie chciałbym poruszać)
    Otóż chodzi o tryb1 powiedzmy timera0.
    Dlatego też załadowałem do rejestru TMOD wartość 01h.
    Następnie kierując sie wskazówkami profesora od zajęć zrozumiałem że aby odliczyć czas 1ms należy załadować do TH|TL wartosc 65536-921
    gdyż jak już sam wywnioskowałem....

    Code:
    1000[µs]*11.0592/12=921,6

    czyli aby timer odliczał czas 1ms musi liczyć do wyliczonej wartości 921.
    Gdy timer się wyzeruje zostanie ustawiona flaga TF0.Którą sprawdzając będe mógł generować większe jednostki czasu .
    Moje pytania brzmią...
    1)Na ile to co tutaj napisałem jest poprawnie(jeżeli gdzieś się pomyliłem proszę o sprostostowanie)
    2)Jak załadować taką wartość do timera
    Ja zrobiłem to w ten sposób jednak nie wiem czy to jest poprawnie
    Code:
    MOV  TH0,0FCH
    
    MOV  TL0,66H

    gdyż liczba 65536-921=64615 co =FC66H
    Jednak zostałem od razu na zajęciach pouczony ze nie tak to powinno wyglądać.Jak z tak dużej liczby poprzez operacje dzielenia i dzielenia modulo wyodrębnić starsza i młodsza część?
    Z góry dziękuję za wskazówki.

    0 17
  • #2 20 Kwi 2009 14:46
    Pawcio89
    Poziom 19  

    Ustawienia TMOD to 00000001 czyli 01h.
    Teraz timer T0 jest ustawiony jako timer z trybie pierwszym i na jego wejście trafia przebieg o częstotliwości około 1MHz, przy częstotliwości oscylatora 12MHz). Daje to okres równy 0,001ms, czyli do odliczenia 1ms potrzeba 1000 takich impulsów.

    0
  • #3 20 Kwi 2009 14:53
    tazit
    Poziom 9  

    No to tylko napisałeś raz jeszcze to co ja.U mnie potrzeba 921 impulsów gdyż częstotliwość oscylatora w Dsm51 to 11,0592MHz.A co odnośnie reszty?

    0
  • #4 20 Kwi 2009 15:13
    Pawcio89
    Poziom 19  

    Zatem tak. Aby licznik był pełny to zapisana liczba to 65535 ale dopiero następny impuls powoduje przepełnienie licznika i jednocześnie ustawienie 1 na znaczniku przepełnienia TF0. W takim razie aby zmierzyć czas 1ms to od liczby przepełnienia czyli od 65536 trzeba odjąć to co obliczyłeś czyli 921. Co daje 64615 czyli FC67h. W takim razie ustawienia to:
    TH0 0FCh
    TL0 67h

    0
  • #5 20 Kwi 2009 15:23
    tazit
    Poziom 9  

    Tak też napisałem.Zauważ że odejmowałem wartosc 921 od 65536 a nie od 65535 dlatego u mnie to jest 0FC66H i zapisalem tak o czym pisałem jednak prosiłem o inny sposób bo tamten był niezadowalający dla prowadzącego zajęcia.Chodzi o to jaką operacje wykonać na liczbie żeby mieć jej mlodsze 4 bity a jaką żeby mieć jej starsze 4 bity.

    chodzi o takie rozwiazanie:

    Code:
    LICZBA  EQU  65536-921
    

    MOV  TL0,"operacja na LICZBA"
    MOV  TH0,"operacja na LICZBA"

    Bardzo bym prosił o dokładne czytanie jaki jest mój problem a nie powielanie tego co już napisałem.Dzieki za zainteresowanie i tak.

    0
  • #6 20 Kwi 2009 15:48
    Pawcio89
    Poziom 19  

    Aby to zrobić zawsze musisz zapisać całą liczbę w systemie szesnastkowym ale nie rozumiem dlaczego uważasz ten sposób za zły. A poza tym to dlaczego 64615 to u Ciebie FC66h a nie FC67h? Nie pomyliłeś się czasem przy obliczeniach?

    0
  • #7 20 Kwi 2009 16:15
    tazit
    Poziom 9  

    Cytat:
    A poza tym to dlaczego 64615 to u Ciebie FC66h a nie FC67h? Nie pomyliłeś się czasem przy obliczeniach?

    Jak najbardziej moja pomyłka.

    Cytat:
    Aby to zrobić zawsze musisz zapisać całą liczbę w systemie szesnastkowym ale nie rozumiem dlaczego uważasz ten sposób za zły

    Ja uważam za dobry.Pisałem ze chodzi o profesora prowadzącego zajęcia.
    Jednak Twoje wyjaśnienie nic mi nie dało.Bo nie podałeś żadnej operacji.

    Jednak już sam doszedłem metodą prób i bledów.
    Prosze o pomoc w zapisie tych operacji akceptowanym przez assemblera dsm51

    Code:
    MOV  TL0, operacja dzielenia LICZBY modulo 256     (da to w wyniku 103(66h)
    
    MOV  TH0, operacja dzielenia LICZBY przez 256 tak aby wyciagnac calosci
    (da to w wyniku 252(0FCh)


    Jakie polecenia odpowiadają mojemu zapisowi?

    0
  • #8 20 Kwi 2009 16:44
    Pawcio89
    Poziom 19  

    Może to pomoże
    DIV AB (podziel)
    Operacja dokonuje dzielenia ośmiobitowej liczby bez znaku zapisanej w akumulatorze przez ośmiobitową liczbę baz znaku zapisaną w rejestrze B. Część całkowita wyniku dzielenia zapisywana jest do akumulatora, reszta zaś do rejestru B.

    0
  • Pomocny post
    #9 20 Kwi 2009 18:24
    Dr.Vee
    VIP Zasłużony dla elektroda

    tazit - profesor ma tutaj rację, bo łamiesz tzw. zasadę DRY - powielasz te same informacje, zamiast skorzystać ze stałej.

    Poczytaj o składni asemblera którego używasz. Być może jest to ten dokument - jeśli tak, to możesz napisać:

    Code:
    mov tl0, <liczba
    
    mov th0, >liczba
    Alternatywnie:
    Code:
    mov tl0, liczba % 256
    
    mov th0, liczba / 256

    Pozdrawiam,
    Dr.Vee

    0
  • #10 20 Kwi 2009 20:22
    adamz74
    Poziom 31  

    Jedna uwaga!

    Za każdym razem, po wystąpieniu przerwania, następuje programowe ładowanie do licznika wartości początkowej, określającej częstotliwość przerwań.
    Należy pamiętać, że od momentu wystąpienia przepełnienia licznika (zgłoszenia przerwania) do momentu przyjęcia przerwania i jego obsłużenia upływa jakiś okres czasu (kilka - kilkanaście cykli maszynowych), a licznik cały czas pracuje i załadowanie wartości początkowej do TL0 spowoduje wykasowanie naliczonej już wartości. To z kolei powoduje wystąpienie pewnych błędów w odmierzaniu czasu.... i teraz wszystko zależy od tego, dlaczego odmierzamy czas i czy możemy pozwolić sobie na błąd.

    Dlatego, przy wpisywaniu wartości początkowej, należy uwzględnić (dodać) bieżącą zawartość licznika. W wielu przypadkach można do tego wykorzystać rozkaz sumy logicznej i ładująca sekwencja rozkazów będzie wyglądała:

    ORL TL0, #LICZBA_L
    MOV TH0, #LICZNA_H

    Pozdr!

    PS. Na miejscu Twojego profesora tego bym się czepiał...

    0
  • #11 21 Kwi 2009 13:42
    tazit
    Poziom 9  

    Dzięki chłopaki.O to chodziło .Zarówno o % i / jak i ładowanie do licznika wartości początkowej.Natomiast mam pytanie jeszcze.
    Napisałeś :

    Cytat:
    Za każdym razem, po wystąpieniu przerwania, następuje programowe ładowanie do licznika wartości początkowej, określającej częstotliwość przerwań.

    Jak sprawdzić kiedy nastąpiło przerwanie i jak to obsłużyć?
    Jednym ze sposobów jest uaktywnienie przerwań dla timerów.Wówczas przerwania są wykonywane automatycznie. zależności od timera są to skoki do adresów 0BH i 1BH gdzie powinienem umieścić podprogramy mojej obsługi przerwania.Czy muszę tu ładować te wartości początkowe.Z wypowiedzi wynika że tak.Przy takim przerwaniu chyba flaga TF0 jest zerowana automatycznie.Prosilbym o jeszcze jakies wyjasnienie.Jakie są zalety i wady takiej obslugi i czy nigdzie sie nie pomyliłem?

    Ale jest jeszcze mozliwosc sprawdzania ręcznego czy flaga TF0 nie jest równa 1.Wówczas skoczyłbym np do jakiejś flagi gdzie następuje ponowne ładowanie timerów,zerowanie flagi TF0 i powrót do wykonywania programu.Z góry dzięki za wyczerpujące odpowiedzi.

    PS.Wielkie dzięki za rozkaz sumy loigicznej wykorzystywany do tego przykładu i wyjaśnienie dokładne.Bardzo mi to pomogło bo pojawiło sie coś takiego na zajęciach ale za nic nie moglem wyciagnąc tych informacji od profesora.

    0
  • #12 21 Kwi 2009 14:24
    romsik
    Poziom 14  

    Dobrze kombinujesz z przerwaniami. Nie musisz nic sprawdzać. Gdy licznik się przepełni flaga TF się ustawi i procesor przejdzie do wykonywania programu pod odpowiednim adresem (jak pisałeś) , o ile oczywiście włączysz sobie przerwanie -Słowo IE bity EA i ET0 lub ET1.
    Po przejściu pod odpowiedni adres flaga tf zostanie skasowana więc jeśli włączyłeś przerwania sprawdzanie flagi TF nie ma sensu. Podobnie nie jest ważne kiedy wystąpi przerwanie- wystąpi zawsze po przepełnieniu licznika i Ty zaraz potem wpisujesz do niego odpowiednią wartość.
    Powodzenia rs
    ps
    ożywanie innych przerwań o wyższych priorytetach może spowodować, że przerwanie od Timera wystąpi później

    0
  • #13 21 Kwi 2009 14:42
    Dr.Vee
    VIP Zasłużony dla elektroda

    Z tym "dodawaniem" korzystając z ORL to bym uważał. Tak naprawdę ma to sens tylko gdy młodsze bity wartości wpisywanej do TL0 są wyzerowane.

    Żeby mieć dokładne odliczanie czasu możesz policzyć ilość cykli od momentu przepełnienia licznika do jego programowego odświeżenia (będzie to stała wartość o ile inne przerwania nie mają wyższego priorytetu) i wpisać zmodyfikowaną stałą. Alternatywnie możesz wykorzystać zwykłe dodawanie:

    Code:
        mov A, #liczba % 256 - 2    ; -2 bo od dowawania do zapisu TL0 miną dwa cykle
    
        add A, TL0
        mov TL0, A
        mov TH0, #liczba / 256
        jnc skip
        inc TH0                     ; dodaj carry do TH0
    skip:

    Edit: zmiana poprawki z -1 na -2.

    Pozdrawiam,
    Dr.Vee

    0
  • #14 21 Kwi 2009 14:43
    tazit
    Poziom 9  

    Masz racje ze nie ma sensu sprawdzac tej flagi( wprzypadku wlaczonej obslugi przerwan) dlatego napisałem o dwóch przypadkach.A ten ze sprawdzaniem to jest ten drugi gdy wylacze przerwania.I taki przypadek tez musz sprawdzić żeby wiedziec o co biega.Jak wtedy ładować liczniki i jak to przebiega?Napewno są jakies opóźnienia bo trzeba dojść do instrukcji gdzie sprawdza sie ta flage a przeciez czas cały czas leci i wykonywane są skoki.

    0
  • #15 25 Kwi 2009 14:03
    romsik
    Poziom 14  

    Dr.Vee a nie powinno być -2, bo przecież są 2 cykle maszynowe "tracone" 1 rozkaz ADD, 2 rozkaz MOV ?
    Co do rozkazu ORL to całkowita racja
    pozdrawiam rs

    0
  • #16 26 Kwi 2009 22:19
    Dr.Vee
    VIP Zasłużony dla elektroda

    A może i -2 :)
    Ważne, że korekta musi być.

    Pozdrawiam,
    Dr.Vee

    0
  • #17 26 Kwi 2009 22:59
    romsik
    Poziom 14  

    I chyba jeszcze jedna zmiana z minus na plus, zgodzisz się Dr. Vee?
    pozdrawiam rs

    0
  • #18 27 Kwi 2009 00:36
    Dr.Vee
    VIP Zasłużony dla elektroda

    Oczywiście masz rację. Powinno być #(liczba + 2) % 256 i #(liczba + 2) / 256.

    Sorry za zamieszanie :)

    Pozdrawiam,
    Dr.Vee

    0