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

Mała prośba o wyjaśnienie ->przerwanie w 51<-

Mariusz_N 07 Lut 2007 17:43 2532 21
  • #1 3540327
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    Witam Wszystkich
    Mam małą prośbę jeśli ktoś może mi podpowiedzieć?
    Jak policzyć wartość (czas poświęcony na obsługę przerwania), którą trzeba dodać do wartości wpisywanej do licznika T0. Mam napisany program timer'a w bascom, który lekko opóźnia. Wiem że błąd wynika z braku korekty wartości o czas, który procesor poświęcił na przerwanie. Proszę o pomoc, bo jakoś tego nie mogę zajarzyć. W postach, które znalazłem na Elektrodzie jakoś pomijany jest ten temat -dosłownie- i tu cytat jeden z wielu "pomijam czas zużyty przez procesor na przerwanie".

    Wyliczoną wartość ładowaną do licznika zwiększałem i zmniejszałem jak to się mówi na oko aż timer przy 20h miał różnice 0,5s ale nie o to chodzi chciałbym wiedzieć jak poprawnie to wyliczyć a nie wpisywać na oko.

    Za wyjaśnienie bardzo dziękuję
    Pozdrawiam Mariusz N.
  • #2 3540380
    markosik20
    Poziom 33  
    Posty: 2261
    Pomógł: 208
    Ocena: 147
    Żeby to policzyć musisz wiedzieć co Bascom wygenerował (chodzi o komendy w ASM) oraz jaki jest czas trwania cyklu maszynowego uP.
    Każda instrukcja ASM trwa tyle i tyle cykli maszynowych (dane w tabelach). Nie wiem czy Bascom w drodze kompilacji tworzy taki plik (np: .a51). Można jeszcze obsługę przerwania napisać tylko w ASM ..i wtedy wiemy dokładnie ile czasu trwa jego obsługa.
  • #3 3540492
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    Baskom generuje cztery pliki z rozszerzeniami DBG, RPT, BIN, HEX niestety nie wiem czy na podstawie któregoś z nich można wywnioskować ile cykli maszynowych zajęło przerwanie? Czyli z tego co napisałeś nie ma możliwości wyliczenia cykli w bascomie jeśli przerwanie nie jest napisane w ASM? Prawdę mówiąc myślałem, że jest to gdzieś wyliczone i podana jest ilość cykli na poszczególne komendy incr, if, decr, return tylko nie bardzo trybiłem jak wyliczyć tą wartość? dodając je kolejno?
  • #4 3540519
    markosik20
    Poziom 33  
    Posty: 2261
    Pomógł: 208
    Ocena: 147
    Można też na podstawie piku .hex ale jest trochę zabawy z tym :).
  • #5 3540586
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    A gdyby to było napisane w ASM to jaka jest zasada obliczania? dodaje się kolejno ilość cykli przypadającą na dany rozkaz? np. jest kolejno pięć rozkazów każdy ma jakąś ilość cykli i kolejno sumuje się a otrzymaną liczbę dodaje się do wartości wpisywanej do licznika?
  • #6 3540697
    algebro
    Poziom 15  
    Posty: 118
    Pomógł: 8
    Ocena: 2
    Musisz policzyć wszystkie cykle rozkazów, zanim ustawisz TL0 (samo ustawianie też trwa 2 cykle).
    Natomiast jeśli wyliczona wartość TL0 odpowiadająca Twojemu zadanemu okresowi przerwań kończy się na zero (X0h), mozesz podczas wykonywania przerwania "w locie" zmienic 4 najstarsze bajty (rozkazem ORL TL0, #X0h).
    Możesz również zastosować drugi tryb ustawienia licznika (licznik 256 cykli), wówczas raz ustawiona zawartość TH0 jest automatycznie przepisywana do TL0.
    Pozdr.
  • #7 3540764
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    Czyli początek przerwania:
    Counter0 = 4096

    to jest już 2 cylke i kolejne polecenie

    też zajmuje pewną ilość cykli? To w takim razie poszczególne komendy w Bascom powinny mieć stałe wartości pytanie gdzie to znaleźć? W help'ie do Bascom jest taka tabela ale tylko dla mnemoników w ASM a ja niestety nie znam ASM i nie bardzo mogę sobie przepisać przerwanie choć z tego co czytałem Baskom dopuszcza mieszanie w programie trochę ASM trochę Bascom. Teraz mam pytanie mogę liczyć na jakąś pomoc w przepisaniu samego przerwania na ASM?
  • Pomocny post
    #8 3540869
    algebro
    Poziom 15  
    Posty: 118
    Pomógł: 8
    Ocena: 2
    Nie znam Bascoma, ale jeśli wartoscią początkową licznika jest 4096 dziesiętne czyli 1000 szestnastkowo, to bardzo dobrze! Nie musisz zmieniac wartości TL0, ponieważ w chwili przerwania przyjmuje odpowiednią wartość (00h). Trzeba tylko w ciągu najbliższych 256 cyklach wpisać do TH0 wartość 10h (16): MOV TH0,#10h. Ale nie wiem jak się robi "wstawki" w Bascomie.
    Natomiast start licznika w programie chyba tylko raz iniciujesz, więc trzeba "te bajty " pominąć.
  • #9 3540906
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    Nie prościej odczytać wartość TH0,TL0. Po wyzerowaniu i zaznaczeniu przerwania licznik cały czas liczy więc wiadomo ile upłynęło czasu od wyzerowania. W większości przypadków wystarcz na początku obsługi przerwania zrobić
    ORL TL0,#mlodszybajtwartoscipocz
    MOV TH0,#starszybajtwartoscipocz
  • #10 3541110
    bolek
    Poziom 35  
    Posty: 4099
    Pomógł: 86
    Ocena: 299
    można zapuścić symulator i zobaczyć ile cykli zjada przerwanie.

    Pliki, które generuje Bascom można zdesaseblerować. W tedy zobaczysz co zrobił bascom i od biedy przeliczysz cykle
  • Pomocny post
    #11 3541201
    bogdan_p
    Poziom 39  
    Posty: 3849
    Pomógł: 525
    Ocena: 120
    zainstaluj sobie program M-IDE Studio for MSC51
    http://www.opcube.com/home.html
    uruchom tylko emulator , wskaż programowi plik xx.hex krok po kroku wykonuj instrukcje programu w odpowiednich oknach masz podgląd co się dziej w uC
  • #12 3543144
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    Ponownie witam
    Dziękuję za podpowiedzi, programik M-IDE Studio for MSC51 zainstalowałem i wczytałem plik hex niestety szczerze mówiąc mimo 2h siedzenia i analizowania krok po kroku nie wiele mi to dało. Nigdy nie używałem takich symulatorów wiec bez opisu trudno mi zrozumieć ich zasadę działania i co pokazują. To są moje początki w programowaniu uP więc mimo wertowania różnych pomocy w formie PDF lub książek nie wszystko jest dla mnie zrozumiałe. Może gdybym znalazł opis w naszym języku takich symulatorów, to szybciej bym zatrybił o co tam chodzi. OK nie będę już zawracał głowy na forum, kiedyś na pewno dojdę do etapu analizowania programów na poziomie cykli maszynowych.

    Pozdrawiam Mariusz N.
  • #13 3543638
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    Wyszukaj w zdeasemblowanym kodzie miejsca

    MOV TL0,#.. albo ORL TL0,#..
    MOV TH0,#..

    prawdopodobnie będą dwa takie miejsca:
    1. inicjacja,
    2. przeładowanie w obsłudze przerwania
    ustaw pułapkę na pierwszą instrukcje
    tj. MOV TL0,
    uruchom program, który zatrzyma się na pułapce
    uruchom ponownie, drugie zatrzymanie to powinna być obsługa przerwania.
    sprawdź zawartość TL0 to będzie ta korekta o którą należy skorygować wartość początkową.
    Trzeba jeszcze uwzględnić w korekcie cykle rozkazu
    modyfikacji TL0 (mov , orl).
    To co pisze to są pobożne życzenia (tak powinno być) ale co BASCOM robi naprawdę ?????

    dołącz hexa sam jestem ciekaw
  • #14 3543681
    john_t
    Poziom 29  
    Posty: 1070
    Pomógł: 127
    Ocena: 89
    Czegoś tu chyba nie rozumiem. Obliczyć (określić) czas potrzebny na przerwanie? Czyli czas wykonania przerwania? Każdy czas nawet pojedynczego cyklu w [ms] można określić za pomocą symulatora działania programu zawartego w kompilatorze Bascom. Uruchamiamy program ale krok po kroku (każdy rozkaz na kliknięcie mychy), zadajemy (wymuszamy) przerwanie przyciskiem T0 lub T1 i gdy skoczy do przerwania kasujemy (zerujemy) w dolnym okienku licznik rozkazów i czasu działania programu. Dajemy krok po kroku i tak przez całe przerwanie gdy się zakończy doczytujemy dane: ilość cykli zegarowych i czas.
  • #15 3543750
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    Chodzi o czas pomiędzy wyzerowanie licznika (zaznaczeniem przerwania) a ponownym załadowaniem licznika wartością początkową w jego obsłudze.
    To jest czas na obsługę stosu (zapamiętanie adresu powrotu i znaczników skok do wektora przerwań), skok do obsługi przerwania, coś jeszcze niewiadomo co tam kompilator i programista wstawi i czas ponownego przeładowania licznika wartością początkową.
    Jeśli zależy tobie na precyzyjnym pomiarze czasu musisz korygować o te kilka(naście) cykli wartość początkową.

    john_t - metoda dobra, ale chodzi o inny czas.
    Wada - jednorazowa - do pierwszych znian w programie (obsłudze przerwania)
  • Pomocny post
    #16 3543891
    john_t
    Poziom 29  
    Posty: 1070
    Pomógł: 127
    Ocena: 89
    No to jeszcze raz (o co Wam chodzi?)

    ‘TO TRWA 6 CYKLI ZEGAROWYCH
    Config Timer0 = Timer , Gate = Internal , Mode = 1
    On Timer0 Timer0_init
    Enable Timer0
    Enable Interrupts
    Start Timer0

    ‘A TO 51 CYKLI
    Timer0_init:
    Counter0 = 4150
    Start Timer0
  • #17 3544238
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    Wielkie dzięki john_t za wytłumaczenie jak sprawdzić to na symulatorze właśnie o coś takiego mi chodziło. Zrobiłem według twojego opisu i wyszło, że do początkowej wartości muszę dodać 57 więc 4096+57=4153. Załadowałem tą wartość do licznika i zrobiłem test urządzenia. Niestety urządzenie przyspiesza około 1sek na 1h więc gdzieś jest błąd chyba, że coś źle na symulatorze zrobiłem. W urządzeniu zastosowałem trymer do korekcji kwarcu 11059200 i stroiłem to ok tydzień temu więc nie podejrzewam, że rozjechał się zegar. Błąd do przyjęcia uzyskałem wpisując do licznika wartość 4140 czyli do wartości początkowej dodałem 44 i timer opóźniał około 0,5s na kilkanaście godzin. Urządzenie ma odliczać czasy od 60h do 90h i różnica 1 sekundy na 1h jest nie do przyjęcia. W poniedziałek będę miał dostęp do miernika F więc jeszcze raz sprawdzę częstotliwość kwarcu.

    Nasunęło mi się jeszcze jedno pytanie może ja walnąłem jakiegoś byka w przerwaniu i teraz tworzą się problemy?
  • #18 3544470
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    john_t napisał:
    No to jeszcze raz (o co Wam chodzi?)


    nie pisze w Bascom ale procedura obsługi przerwania chyba wygląda mniej więcej tak

    PrzerwanieT0: /początek procedury
    Counter0=4096; /wartość początkowa T0
    xxxxxx
    xxxxxx
    xxxxxx
    xxxxxx
    koniec: /powrót z przerwania


    chodzi o czas
    od wystąpienia przerwania tzn. T0=0
    do Counter0
    mniej więcej - ponieważ znajomość Bascoma tutaj nie wystarczy ponieważ rozwinięcie asemlerowe funkcji Couter0 będze wyglądać:

    Counter0:
    xxxxxx
    xxxxxx
    xxxxxx
    MOV TL0,....
    MOV TH0,... /chodzi precyzyjnie o czas do tego miejsca
    xxxxxx
    RET


    pisanie w Bascom nie zwalnia od znajomoci asemblera i procesora :D


    godzine póżniej

    zainstalowałem to cudo
    z :

    Timer0_init:
    Counter0 = 4150
    Start Timer0
    Return

    zrobił:

    
    vektor przerwania:
    
    C:0x000B    020088   LJMP     C:0088
    
    
    Timer0_init:
    C:0x0088    C0D0     PUSH     PSW(0xD0)
    C:0x008A    C2D3     CLR      RS0(0xD0.3)
    C:0x008C    C0E0     PUSH     ACC(0xE0)
    C:0x008E    C0F0     PUSH     B(0xF0)
    C:0x0090    C083     PUSH     DPH(0x83)
    C:0x0092    C082     PUSH     DPL(0x82)
    C:0x0094    C000     PUSH     0x00
    C:0x0096    C001     PUSH     0x01
    C:0x0098    C002     PUSH     0x02
    C:0x009A    C003     PUSH     0x03
    C:0x009C    C004     PUSH     0x04
    C:0x009E    C005     PUSH     0x05
    C:0x00A0    C006     PUSH     0x06
    C:0x00A2    C007     PUSH     0x07
    C:0x00A4    C008     PUSH     0x08
    C:0x00A6    C009     PUSH     0x09
    C:0x00A8    C00A     PUSH     0x0A
    C:0x00AA    C00B     PUSH     0x0B
    C:0x00AC    C00C     PUSH     0x0C
    C:0x00AE    C00D     PUSH     0x0D
    C:0x00B0    C00E     PUSH     0x0E
    C:0x00B2    C00F     PUSH     0x0F
    C:0x00B4    C010     PUSH     0x10
    C:0x00B6    C011     PUSH     0x11
    Counter0 = 4150:
    C:0x00B8    C28C     CLR      TR0(0x88.4)
    C:0x00BA    758A36   MOV      TL0(0x8A),#0x36
    C:0x00BD    758C10   MOV      TH0(0x8C),#0x10
    Start Timer0:
    C:0x00C0    D28C     SETB     TR0(0x88.4)
    C:0x00C2    D011     POP      0x11              /interesuje nas czas do tego
    C:0x00C4    D010     POP      0x10
    C:0x00C6    D00F     POP      0x0F
    C:0x00C8    D00E     POP      0x0E
    C:0x00CA    D00D     POP      0x0D
    C:0x00CC    D00C     POP      0x0C
    C:0x00CE    D00B     POP      0x0B
    C:0x00D0    D00A     POP      0x0A
    C:0x00D2    D009     POP      0x09
    C:0x00D4    D008     POP      0x08
    C:0x00D6    D007     POP      0x07
    C:0x00D8    D006     POP      0x06
    C:0x00DA    D005     POP      0x05
    C:0x00DC    D004     POP      0x04
    C:0x00DE    D003     POP      0x03
    C:0x00E0    D002     POP      0x02
    C:0x00E2    D001     POP      0x01
    C:0x00E4    D000     POP      0x00
    C:0x00E6    D082     POP      DPL(0x82)
    C:0x00E8    D083     POP      DPH(0x83)
    C:0x00EA    D0F0     POP      B(0xF0)
    C:0x00EC    D0E0     POP      ACC(0xE0)
    C:0x00EE    D0D0     POP      PSW(0xD0)
    C:0x00F0    32       RETI   
    Return:
      


    teraz już łatwo policzyć
  • #19 3544962
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    Czy dobrze licze i wychodzi 53 ??
  • #20 3545447
    algebro
    Poziom 15  
    Posty: 118
    Pomógł: 8
    Ocena: 2
    Mnie również wyszło 53 bajty. Zastanawiam się tylko, czy nie możesz raz włączyć licznika i tylko go korygowac w przerwaniu? Zamiast zatrzymywac go za każdym razem w celu wpisania wartości początkowej i ponownego włączania???

    Tylko wtedy zmieni się ilość cykli. ;-)

    I jeszcze raz przypominam, że uzywając wartości wyjściowej 4096 (1000h), możesz tylko zmieniać zawartość TH0. Oczywiście jeśli raz zainicjujesz w programie głównym ten licznik i przerwania od niego ( bez zbędnych zatrzymywań i wznowień w przerwaniu).
  • #21 3545543
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    55 z LJMP to jest minimum;
    w pewnich przypadkach może być więcej,
    poczytaj na temat warunków przyjęcia, obsługi i priorytetów przerwania.
    Dlatego metoda z ORL TL0,#.. jest dokładniejsza

    Dodano po 8 [minuty]:

    algebro napisał:
    uzywając wartości wyjściowej 4096 (1000h), możesz tylko zmieniać zawartość TH0. .


    genialna obserwacja pod warynkiem, że do TH0=0x10 wpiszesz bezpośrednio bez udziału funkcji Counter0= ponieważ to ona zatrzymuje licznik. Nie trzeba używać Start.
  • #22 3547300
    Mariusz_N
    Poziom 18  
    Posty: 291
    Pomógł: 32
    Ocena: 55
    Czyli nie jest to takie proste jak myślałem :( niestety urządzenie musze oddać w przyszłym tygodniu a to za mało czasu żeby wgryźć się w ten temat i dokładnie zrozumieć warunki przyjęcia, obsługi i priorytetów przerwania jak i również zapoznać się z ASM. Zostało mi ustawić ten parametr na tak zwane oko a w późniejszym czasie ponownie przysiąść do tych przerwań :idea:. W sumie temat można zamknąć.

    Dziękuję za podpowiedzi i do następnego razu.
    Pozdrawiam Mariusz N.

Podsumowanie tematu

✨ Dyskusja dotyczy problemu precyzyjnego obliczenia czasu obsługi przerwania w mikrokontrolerze z wykorzystaniem timera T0 programowanego w Bascom. Autor pyta, jak uwzględnić czas procesora poświęcony na obsługę przerwania, który wpływa na dokładność pomiaru czasu i powoduje opóźnienia. W odpowiedziach podkreślono, że aby dokładnie wyliczyć czas przerwania, należy znać liczbę cykli maszynowych wykonywanych przez instrukcje asemblerowe generowane przez Bascom, co można ustalić analizując plik .hex lub deasemblując kod. Zalecane jest także użycie symulatora (np. M-IDE Studio for MSC51) do krokowego śledzenia wykonania programu i pomiaru cykli przerwania. Wskazano, że czas obsługi przerwania obejmuje m.in. zapisywanie stanu stosu, skok do wektora przerwania oraz ponowne załadowanie licznika. Proponowano korektę wartości początkowej licznika o sumę cykli przerwania, co można zrobić przez modyfikację rejestrów TH0 i TL0. Dyskutowano także o możliwości mieszania kodu Bascom z asemblerem dla precyzyjnej kontroli czasu. Pomimo prób i testów, autor nadal obserwował niewielkie błędy czasowe, co wskazuje na złożoność problemu i konieczność głębszej znajomości asemblera i architektury mikrokontrolera. Ostatecznie autor zdecydował się na korektę "na oko" z zamiarem powrotu do tematu po zdobyciu większej wiedzy.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA