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.

[PICxxxxx] Ustawianie timera z dokładnością do 1 cyklu

maciej_jl 02 Lut 2011 09:05 2444 18
  • #1 02 Lut 2011 09:05
    maciej_jl
    Poziom 8  

    Witam.

    Zmagam się z problemem ustawienia timera0 na konkretną wartość cykli.
    (Na razie na pic16f628a, ale później program będzie wgrany na coś innego.)

    np. chce uzyskać przerwanie co 100 cykli timera:

    Code:
    static void interrupt isr()
    
    {
       if (T0IF)
       {      
          TMR0 =  155; //255 - 100 cykli
          T0IF = 0;
          // kod przerwania
       }   
    }


    problem w tym że powyższy kod nie uwzględnia:
    1) czasu na zapisanie kontekstu przy przewaniu,
    2) czasu wykonywania instrukcji przed TMR0 = XX.
    3) czasu po jakim timer wznowi odliczanie po zapisaniu rejestru licznika timera.

    Wiem tylko że zapisanie do rejestru timera powoduje przerwanie odliczania na 2 cykle (jeden podczas zapisu i następny cykl). Jeżeli chodzi o czas wykonywania instrukcji w procedurze obsługi przerwania to można to policzyć przeglądając listing po kompilacji. Niestety nie mogę się doszukać ile czasu zejdzie na zapisanie kontekstu przerwania i czy jest to zależne od konkretnego modelu, rodziny (architektury) i czy jest to wartość zawsze stała.
    Pewnie jest to gdzieś w datasheet, ale jakoś skutecznie to umyka mojej uwadze.

    Dziękuję za wszelką dyskusję.

    0 18
  • #3 02 Lut 2011 10:34
    maciej_jl
    Poziom 8  

    Zgadza się, aby policzyć ile czasu zajmie wykonanie kodu potrzeba kodu maszynowego (napisałem to w pierwszym poście). Ja będę pisał w C i tylko zobaczę sobie na listing programu gdzie jest to przetłumaczone na assemblera i wprowadzę odpowiednią poprawkę (zmiana wartości timera) do kodu w c.

    Chce precyzyjnie odmierzać czas do próbkowania wejścia z modułu radiowego 433 MHz.
    Chodzi o komunikację radiową z pilotami na keeloq. Teraz mam Fosc 4MHz i sygnał Te 400us, co przy 3 próbkach daje mi 133 us, a więc Timer0 bez prescalera na 133 i oczywiście działa, ale w ostatecznej wersji (Fosc 20 lub 32MHz) chciałbym już to wyliczyć dokładnie. Tyko nie znam czasu zapisywania kontekstu i skoku do procedury obsługi przerwania.

    Ale zastosowań na dokładne ustawianie czasu można by wyliczać mnóstwo. np. do softwarowego pwm lub generatora czestotliwości. W końcu czasem 4 czy 5 kanałów to za mało.

    0
  • #4 02 Lut 2011 10:54
    Urgon
    Poziom 36  

    AVE...

    Tutaj masz przykład tego, jak możesz napisać kod w C dla użycia przerwania timera do odmierzania czasu...

    Druga rzecz: czemu nie użyjesz portu z przerwaniami zewnętrznymi i nie ustawisz sobie przerwania na zbocze wznoszące sygnału lub nie użyjesz PICa z wewnętrznym komparatorem i przerwaniem na nim? Łatwiej czekać jest na zdarzenie, niż próbkować, czy się nie zdarzyło...

    1
  • #5 02 Lut 2011 11:30
    maciej_jl
    Poziom 8  

    Tylko że czas ma znaczenie (długości sygnałów, preambuła itp) i gdybym chciał to zrobić na przerwaniu, to musiałbym tak czy tak wewnętrznie mierzyć czasy pomiędzy sygnałami i różnymi ich kombinacjami. (2-ga strona opisuje jak wygląda sygnał pojedyńczej transmisji http://www.modernsoft.pl/Dokumenty/Programator200.pdf), a dodatkowo musiałbym dysponować algorytmem na odfiltrowanie zakłóceń. Robiąc to na próbkowaniu, zakłócenia powodują jedynie błędny kod lub brak odczytu, bez dodatkowego zastanawiania się jakiego typu są to zakłócenia.
    W skrócie będzie to tak:
    próbkowanie - czytanie danych w sposób jaki oczekujemy.
    przerwania - czytanie wszystkiego i nakładanie na oczekiwany format.
    Moim zdaniem to pierwsze jest dużo łatwiejsze, ale może po prostu nie mam pomysłu.
    Wstawił bym kod, ale w większości pochodzi on z
    KeeLoq Decoder License Disk i trzeba zaakceptować regulamin zanim zacznie się z tego kodu korzystać.

    0
  • #6 02 Lut 2011 11:50
    Urgon
    Poziom 36  

    AVE...

    Można to zrobić sprzętowo na dwóch komparatorach i kilku rezystorach i kondensatorach. Najpierw mierzysz przez ADC poziom szumu i za pomocą źródła napięcia odniesienia i pierwszego komparatora odejmujesz go od sygnału. Potem sygnał rozdzielasz na dwa układy RC, jeden ze stałą czasową Te, drugi ze stałą czasową 2Te. Sygnał z 1Te dajesz jako Twój sygnał zegarowy, oba dajesz na wejścia komparatora. W ten sposób będziesz mieć sygnał zegarowy i odpowiadający mu sygnał danych... Tak mi się przynajmniej wydaje, że to zadziała...

    Przy wyższej częstotliwości zegara mikrokontrolera nie będziesz musiał się tak ściśle trzymać czasów, bo Twój kod w przerwaniu będzie wykonany bardzo szybko. Musisz tylko sobie dobrać wartość preskalera. Inną opcją jest ustawienie timera na zliczanie czasu, w czasie gdy wejście generuje impuls na zbocze. Przy każdym impulsie odczytujesz stan licznika timera i go zerujesz...

    0
  • #7 02 Lut 2011 12:28
    maciej_jl
    Poziom 8  

    Wyjście z modułu radiowego mam cyfrowe, więc nie interesują mnie szumy na analogu, tylko przekłamania które przedostaną się do sygnału cyfrowego. mogę stosować jakiś filtr RC by wyłapać te krótsze niż 1Te. Ale obecne rozwiązanie obciąża uC przy 4MHz (a będzie szybszy) na ok 30%, więc w zupełności wystarczy.

    0
  • #8 02 Lut 2011 12:49
    Urgon
    Poziom 36  

    AVE...

    Spróbuj tej drugiej metody z użyciem wejścia do generowania przerwania. Tak się robi mierniki częstotliwości i LC na PICach...
    Ustawiając najpierw przerwanie na zbocze narastające, a po starcie timera na opadające możesz mierzyć długość impulsu. Przy szybkim zegarze nie będzie problemu z czasami...

    0
  • #9 02 Lut 2011 13:04
    maciej_jl
    Poziom 8  

    No fakt. To z przestawianiem zbocza z wznoszącego na opadające może być dobre. Teraz robię prototyp to zostawię, ale coś mi się wydaje że jednak przepiszę ten kawałek kodu, oczywiście dzięki za wskazówkę.

    Jednak sprawa wyliczenia dokładnej wartości dla timera jest dalej otwarta, zastosowań jest mnóstwo, więc tak czy tak czekam na podpowiedzi w tej sprawie. Czytałem gdzieś porównanie PIC <-> AVR lub ST i tam było napisane ile czasu zajmuje przejście do procedury obsługi przerwania, ale teraz nie mogę się tego doszukać.

    0
  • #10 02 Lut 2011 13:12
    Urgon
    Poziom 36  

    AVE...

    Rób prototyp od razu z dedykowaną częstotliwością zegara...

    Możesz też użyć modułu CCP, ustaw go w tryb Capture na każde zbocze opadające. Zamiast mierzyć długość impulsu, zmierzysz długość przerw między impulsami. W ostatecznym rozrachunku wyjdzie na to samo...

    0
  • #11 02 Lut 2011 13:44
    maciej_jl
    Poziom 8  

    Cytat:
    W ostatecznym rozrachunku wyjdzie na to samo...

    Niestety nie, Bity są kodowane w 3 cyklach Te
    1: --_
    0: -__
    (minus = stan wysoki, podkreślenie stan niski)
    czyli znaczenie ma czas trwania stanu wysokiego,
    zaś w preambule znaczenie ma czas trwania stanu niskiego

    co do zegara masz rację, ale na razie chodzi o oszacowanie czy da się zrobić software'owo dekodowanie keeloq'a i ile to zużyje zasobów, by kupić do tego odpowiedni mikrokontroler w jak najniższej cenie. Bo raczej będziemy ruszać z produkcją seryjną. Rozwiązanie podsunięte do tej pory to albo sprzętowy dekoder HCS50X + atmega do sterowania. Ja natomiast proponuję rozwiązanie z 1-dnym PIC'em który załatwił by obie te żeczy i do tego był znacznie tańszy niż sama tylko atmega.

    0
  • #12 02 Lut 2011 13:52
    Urgon
    Poziom 36  

    AVE...

    Przy zboczu opadającym będzie to wyglądać tak:

    Code:
    -__-__ - 3Te
    
    --_-__ - 2Te
    -__--_ - 4Te
    --_--_ - 3Te

    Ponieważ pierwsza i czwarta kombinacja są takie same, to musiałbyś sprawdzać, co było przed nimi, lub po nich, by móc określić dokładnie sekwencję bitów. Ale to do zrobienia jest po odebraniu sygnału, w fazie dekodowania...
    Nadal użycie komparatora i dwóch obwodów RC o różnych stałych czasowych pozwoliłoby Ci generować sprzętowo zdekodowany sygnał...

    0
  • #13 02 Lut 2011 14:25
    dondu
    Moderator Mikrokontrolery Projektowanie

    maciej_jl napisał:
    NCzytałem gdzieś porównanie PIC <-> AVR lub ST i tam było napisane ile czasu zajmuje przejście do procedury obsługi przerwania, ale teraz nie mogę się tego doszukać.

    W PIC18F87K90 pisze:

    napisał:
    For external interrupt events, such as the INTx pins or the PORTB input change interrupt, the interrupt latency will be three to four instruction cycles. The exact latency is the same for one or two-cycle instructions.

    Czy tego szukałeś?

    0
  • #14 02 Lut 2011 15:03
    maciej_jl
    Poziom 8  

    Tak, tylko że dla przerwania generowanego przez timery.

    0
  • #16 03 Lut 2011 08:59
    maciej_jl
    Poziom 8  

    No i znalazłem.
    APPLICATION NOTE - BENCHMARK ST72 vs. PIC16
    Na stronie 10 jest tabela "Interrupt reaction time". Wynika z niej że czas jaki upłynie od momentu wystąpienia przerwania do rozpoczęcia procedury obslugi wyniesie 1-2 cykli + 2 cykle na skok w zależności czy aktualnie wykonywana instrukcja jest 1-dno czy 2-wu "cyklowa". Potem można już wszystko policzyć, zapisanie kontekstu + inne instrukcje.
    Nasuwa mi się taki wniosek, że skoro ten czas to nie jest wartość stała, to zapisując wartość do rejestru timer'a w procedurze obsługi przerwania, to tracimy dokładność precyzyjnego odmierzania czasu gdyż błąd ten może się kumulować i przy dłuższym działaniu może on stać się znaczący. Choć rozwiązaniem problemu może być odczytanie rejestru timera, wyliczenie korekty i zapisanie ;)

    Dziękuję kolegom za podpowiedzi. Pozdrawiam.

    0
  • #18 07 Lut 2011 20:40
    94075
    Użytkownik usunął konto  
  • #19 23 Gru 2011 21:05
    viman.eu
    Poziom 9  

    zapis konkretnej liczby (n.p. 100dec=64hex) do TMR0
    movlw 0x64,W
    movwf TMR0

    0