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

Mikrokontroler 8051. Obsługa licznika T0 z obsług± przerwań.

filip10 20 Cze 2015 15:55 1065 20
  • #1 20 Cze 2015 15:55
    filip10
    Poziom 9  

    Napisałem program obsługi licznika T0 z obsług± przerwań co 10ms.
    Proszę o sprawdzenie czy wszystko jest ok.

    Kod: matlab
    Zaloguj się, aby zobaczyć kod

    Dodano po 22 [minuty]:

    Po zdebugowaniu i wci¶nięciu run wyskakuje taki bł±d:
    *** error 65: access violation at C:0x0020 : no 'execute/read' permission

    0 20
  • Arrow Multisolution Day
  • #2 20 Cze 2015 16:32
    greg789
    Poziom 16  

    Jaka jest częstotliwo¶ć generatora ?
    Po wł±czeniu przerwań twój program wylatuje w kosmos dodaj na końcu np.:
    test: sjmp test

    0
  • Pomocny post
    #3 20 Cze 2015 16:42
    kemot55
    Poziom 30  

    Twój program nie ma zakończenia. END nic nie załatwia. Przed END powinien znaleĽć się taki zapis:

    Kod: asm51
    Zaloguj się, aby zobaczyć kod

    Czyli pętla pusta.
    Ale i tak masz w obsłudze przerwania jaki¶ dziwny zapis. Po co zapisujesz do pamięci RAM (adres 30H) zawarto¶ć młodszej czę¶ci rejestru licznika?
    Tam powinno być raczej wpis wła¶ciwych warto¶ci do TH0 i TL0 (o ile chcesz otrzymać stały okres przerwania).

    1
  • Pomocny post
    #4 20 Cze 2015 16:49
    greg789
    Poziom 16  

    A dlaczego zamiast T0 konfigurujesz T1 ?
    Jest
    MOV TMOD, #01010000B ;USTAWIENIE ZRODLA I TRYBU 1
    A powinno być odwrotnie
    MOV TMOD,#00000101B

    1
  • #5 20 Cze 2015 22:59
    filip10
    Poziom 9  

    Konfiguracje już poprawiłem.
    Częstotliwo¶ć generatora to 12 MHz.

    0
  • #6 20 Cze 2015 23:19
    greg789
    Poziom 16  

    Używasz jakiego¶ emulatora ?
    Jakiego bo wygl±da to na bł±d emulatora.
    A z twojej konfiguracji wynika że licznik jest taktowany z zewn±trz, tak ma być ?

    0
  • #7 20 Cze 2015 23:40
    filip10
    Poziom 9  

    Dokładnie to co¶ takiego: uVision IDE, firmy Keil dla 8051, wersja 9.52

    0
  • Arrow Multisolution Day
  • #8 21 Cze 2015 15:10
    filip10
    Poziom 9  

    W pierwszym po¶cie zamieniłem kod na poprawiony.
    Czy teraz wszystko jest w porz±dku ?

    0
  • #9 21 Cze 2015 16:10
    greg789
    Poziom 16  

    Wprowadziłem kilka poprawek porównaj.
    Nie korygowałe¶ zawarto¶ci licznika T0 na 10 ms. w przerwaniu.

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    0
  • #10 21 Cze 2015 16:22
    filip10
    Poziom 9  

    Sk±d wzięły się warto¶ci wpisywane do TH0 i TL0 (240 i 226)?

    A ten program jest zły?

    Kod: matlab
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #11 21 Cze 2015 18:07
    greg789
    Poziom 16  

    wyliczyłem dla 10 ms.
    Przy zegarze 12 MHz cykl rozkazowy trwa 1 us (tak jest taktowant licznik T0)
    1 ms = 1000 us , czyli 10ms = 10000 cykli
    65536 - 1000 = 55536 dec = d8f0 hex
    U ciebie widzę jeszcze jedn± nieprawidłowo¶ć , w głównej pętli czekaj±cej na przerwanie 2 x masz dostęp do rej. IE, a podczas tego dostępu przerwanie nie może być wykonane.
    Takich sytuacji należy unikać je¶li chcesz zachować stał± czasow± przerwań.

    Pu¶ć sobie obie wersje w emulatorze i porównaj czasy między przerwaniami.
    Możesz jeszcze w przerwaniu ORL TL0,#F0 zamienić na ORL TL0,#f2 :D

    1
  • Pomocny post
    #12 21 Cze 2015 18:24
    kemot55
    Poziom 30  

    W pierwszym kodzie pojawia się czas 10us (mikrosekundy), póĽniej milisekundy.
    Rozumiem, że ma być 10ms?

    Dla 10us można jeszcze zautomatyzować przeładowanie timera np. tak:

    Kod: asm51
    Zaloguj się, aby zobaczyć kod

    Przy 10ms musi być tak jak napisał kolega greg789 z tym, że dobry kompilator poradzi sobie z policzeniem warto¶ci wpisywanych do rejestrów
    np. tak:
    Kod: asm51
    Zaloguj się, aby zobaczyć kod

    1
  • #13 21 Cze 2015 18:43
    filip10
    Poziom 9  

    A mógłby¶ mi jeszcze powiedzieć czemu w Twoim programie jest w 6 linijce orl TL0,#0F0h a nie MOV TL0,#0F0? Orl to chyba suma logiczna i nie rozumiem dlaczego to tak jest zapisane.

    0
  • Pomocny post
    #14 21 Cze 2015 19:31
    PDT
    Poziom 24  

    filip10 napisał:
    A mógłby¶ mi jeszcze powiedzieć czemu w Twoim programie jest w 6 linijce orl TL0,#0F0h a nie MOV TL0,#0F0? Orl to chyba suma logiczna i nie rozumiem dlaczego to tak jest zapisane.


    Wychylę się i podpowiem.

    Przerwanie podejmowane jest przy przej¶ciu licznika timera TH0,TL0 do stanu 0. Jednak timer liczy dalej 1,2.., ile jest w chwili przeładowania w procedurze obsługi, tego nie wiemy. Zależy to od instrukcji po której przerwanie nast±piło (nawet do 4 cykli) i ilo¶ci cykli w samym przerwaniu. Ale normalnie to jest rz±d kilku. Dlatego taka instrukcja ORL TL0,#F0 ustawi starsze bity nie tr±caj±c młodszych. Uwzględnimy w ten sposób uchyb pomiaru czasu. A i tak gubimy 1 cykl, ten pomiędzy odczytem a zapisem.
    W języku C prawidłowo powinni¶my zapisać to TL0+=0xF1.

    Pzdr

    1
  • #15 23 Cze 2015 14:55
    filip10
    Poziom 9  

    Mam jeszcze jeden problem.

    Chcę napisać program który porównuje 2 liczby 8-bitowe i wynik porównania
    to wyj¶cie 3 bitowe ( = < >)
    Napisałem co¶ takiego ale się nie kompiluje nawet.

    START:
    MOV R1,#10
    MOV R2,#20
    MOV A,R1
    CJNE A,R2,skok
    SETB P1.0
    SJMP dalej
    skok: JC mniejszy
    SETB P1.1
    SJMP dalej
    mniejszy:
    SETB P1.2
    dalej:
    end

    0
  • #16 23 Cze 2015 15:03
    greg789
    Poziom 16  

    Zmień w 5 linijce
    CJNE A,R2,skok
    na
    CJNE A,2,skok

    w tym rozkazie nie możesz użyć jako adres R2 , ale możesz to zrobić jako adres 02 wyjdzie na to samo pod warunkiem że korzystasz z 0 banku rejestrów

    0
  • #17 23 Cze 2015 15:19
    filip10
    Poziom 9  

    *** error 65: access violation at C:0x0014 : no 'execute/read' permission

    W kompilacji 0 błędów ale potem przy Run dostałem tak± odpowiedĽ.

    0
  • #18 23 Cze 2015 15:30
    greg789
    Poziom 16  

    A to nie jest taki sam bł±d jak poprzednio ?
    dodaj na końcu np.
    dalej: sjmp dalej
    albo
    dalej: sjmp start
    bo symulator po skoku dalej trafia na .... no wła¶nie na co? ;)

    0
  • #19 23 Cze 2015 15:52
    filip10
    Poziom 9  

    CPL P1.0
    CPL P1.1
    CPL P1.2
    START:
    MOV R1,#10
    MOV R2,#20
    MOV A,R1
    CJNE A,2,skok
    SETB P1.0
    SJMP dalej
    skok: JC mniejszy
    SETB P1.1
    SJMP dalej
    mniejszy:
    SETB P1.2
    dalej:
    sjmp dalej
    end

    Zanegowałem jeszcze na pocz±tku wyj¶cia, żeby się póĽniej ¶wieciły tylko te które powinny.
    My¶lę, że już powinno być ok. :)
    Zgadza się ?

    0
  • Pomocny post
    #20 23 Cze 2015 17:32
    greg789
    Poziom 16  

    Niby dobrze, ale mógłby¶ się postarać , bo np, przy drugim przej¶ciu będzie kicha.
    Ja bym porz±dnie ustawił piny na starcie
    zamiast CPL dał
    START: MOV P1,#0FFh
    pomy¶l dlaczego ?

    1
  • Pomocny post
    #21 23 Cze 2015 20:03
    kemot55
    Poziom 30  

    Małe wyja¶nienie.
    Jeżeli porównanie ma ustawiać linię portu to dobrze by było zainicjować port (jeden z 3 bitów) zerami. Czyli:

    Kod: asm51
    Zaloguj się, aby zobaczyć kod

    zamiast
    Kod: asm51
    Zaloguj się, aby zobaczyć kod


    Inn± spraw± jest to, że tak zorganizowane wyj¶cie informacji jest generalnie do kitu. Wydajno¶ć pr±dowa portu w stanie H jest o wiele niższa niż w stanie L.
    Bezpo¶rednio do portu można podpi±ć diodę LED w taki sposób, żeby zapalać j± ustawieniem na porcie zera a nie jedynki. Po resecie wszystkie linie portu s± ustawiane do stanu wysokiego.

    1