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.

LPC1768 - realizacja opoźnienia

mariuszterba 12 Maj 2014 09:40 1302 13
  • #1 12 Maj 2014 09:40
    mariuszterba
    Poziom 10  

    Jestem już po wgraniu programów demonstracyjnych dla tego procesora. Zabrałem się za sztandarowy program dla mikrokontrolerów czyli mruganie diodą. Opóźnienia realizuję poprzez pętlę for jednak zbyt dokładnie nie jestem w stanie określić czasu trwania opóźnienia od wartości w zmiennej i. Wcześniej kiedy pisałem programy w asemblerze 8051 bez problemu wiedziałem ile cykli trwa dany rozkaz i na tej podstawie realizowałem bardzo dokładne opóźnienia. Mój kod przedstawiam poniżej, a zarazem pytam jak zrealizować opóźnienie powiedzmy co do 1 ms w LPC1768 ?

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 13
  • Pomocny post
    #2 12 Maj 2014 09:51
    mickpr
    Poziom 39  

    mariuszterba napisał:
    Opóźnienia realizuję poprzez pętlę for jednak zbyt dokładnie nie jestem w stanie określić czasu trwania opóźnienia od wartości w zmiennej i.
    Bo to zależy od częstotliwości taktowania mikrokontrolera, zastosowanej zmiennej (char/int/long/...) i włączonej optymalizacji.
    Możesz stosować opóźnienia w stylu delay_ms/us/s (w załaczniku)... ale to takie "doraźne" rozwiązania.
    W realnych projektach realizowanie opóźnienia pętlą - to pomyłka. Zastosuj timery.

    0
  • Pomocny post
    #3 12 Maj 2014 10:16
    1869650
    Użytkownik usunął konto  
  • #4 12 Maj 2014 11:56
    mickpr
    Poziom 39  

    KRD napisał:
    przy czym jeśli co sekundę to wstawiasz w main
    Należy uzupełnić, że aby to (w miarę) działało - pętla main musi chodzić jak najszybciej jak to możliwe.
    Inaczej należałoby doliczyć opóźnienie (czasem niestety zmienne) jakie występuje w samej pętli main (spowodowane obsługą pozostałych elementów programu).

    0
  • Pomocny post
    #5 12 Maj 2014 13:25
    KamilCWK
    Poziom 11  

    Podaję ładniejszą formę obsługi opóźnienia na SysTick:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #6 12 Maj 2014 13:35
    mickpr
    Poziom 39  

    Jeśli program musi używać delay w tej postaci, to jest źle zaprojektowany.
    Skoro chodzi o zwykłe miganie diodą, to o wiele lepszy pomysł jest taki :
    http://msys-mv.blogspot.com/2010/11/configuring-and-playing-with-timer-of.html

    Przy zastosowaniu timer'a mikrokontroler:
    - jest w stanie zapewnić o wiele dokładniejsze odmierzanie czasu.
    - może wykonywać w międzyczasie inne (z reguły ważniejsze) zadania.

    Przy zastosowaniu pętli zwalniających
    - można co do taktu wyliczyć czas ich trwania (po desassemblacji, albo pisząc funkcje wprost w assemblerze),
    - można zrealizować minimalne opóźnienie (np wstawiając pojedynczą instrukcję NOP), których Timer'em się nie uzyska.

    Wybór drogi zależy od kierunku - w jakim chcemy iść.

    0
  • #7 12 Maj 2014 13:40
    1869650
    Użytkownik usunął konto  
  • #8 12 Maj 2014 13:47
    KamilCWK
    Poziom 11  

    Potwierdzam, jest to marnowanie czasu :)
    Kod poprostu demonstruje w jaki sposób można zrealizować w inny sposób opóźnienie. Może się np. przydać przy realizacji komunikacji z wyświetlaczem opartym na HD44780.

    0
  • Pomocny post
    #9 12 Maj 2014 17:19
    Badmaneq
    Poziom 23  

    Ja też dorzucę swoje 5 gr :) Poniżej delay oparte o timer, chcąc wykorzystać inny timer należy LPC_TIM0 zamienić na inny np. LPC_TIM1.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #10 12 Maj 2014 17:31
    mickpr
    Poziom 39  

    Badmaneq napisał:
    delay_ms(1000); //czeja 1000 ms
    Nie obraź się, ale to dalej jest do bani. Tym razem jedynym "ułatwieniem" jest bezczynne czekanie tyle - że na przerwanie - co kłóci się z ideą Timerów jako takich.
    Kod :
    Badmaneq napisał:
    while( !(LPC_TIM0->IR & 0x01) );
    zatrzymuje bezczynnie MCU.

    Jedynym sensownym odmierzaniem czasu jest powierzenie liczenia hardware, a nie "liczenie software-owe":
    Główny program się stale wykonuje, a po określonym czasie następuje sprzętowe przerwanie Timer'a które "coś ma zrobić".
    To trochę jak programowanie Windows-ów (zdarzeniowe). Nie czekamy na ruch myszki. To ruch myszki wywołuje jakiś ciąg zdarzeń.
    Głównym zadaniem nieobciążonego systemu jest realizacja tzw. "idle task".
    Tylko "nic nie robienie" i stałe oczekiwanie na zdarzenia umożliwi szybką reakcję na nie.

    Gdy będziesz miał zadanie tylko migać jedną diodą - to nie ma znaczenia.
    Ale jeśli takich diod będzie 10 czy 100 - i każda inaczej będzie migać, to software-owo się praktycznie nie da tego zrealizować.

    0
  • #11 12 Maj 2014 17:52
    Badmaneq
    Poziom 23  

    Nie obrażam się :)
    Miało być delay, więć napisałem delay. W LPC1768 są 4 timery + SysTick, jeden można "zmarnować". Jeżeli będzie chciał aby podczas czekania "robiło się" coś jeszcze zastosuje schemat, który pokazał KRD. Uważam, że na początku jako początkujący będzie wykorzystywał opóźnienia "zatrzymujące" MCU. Dobrze, że dyskusja się rozwinęła, dzięki temu mariuszterba ma możliwość wyboru.

    0
  • #12 12 Maj 2014 17:55
    mickpr
    Poziom 39  

    Badmaneq napisał:
    jeden można "zmarnować"
    Niekoniecznie.
    Jednym timerem możesz zrealizować wiele funkcji na raz.
    Przykładowo: robisz timer który odmierza czas 10mS (tyknięcie). Następnie ustalasz sobie że co 1 tyknięcie będzie wykonywana część A, co 3 tyknięcia - część B, co 10 tyknięć część C itd..
    Wiesz o co mi chodzi? Możesz z jednego timera zrobić zegar, który będzie sterował kilkunastoma cyklicznymi procesami.
    Do tego odpowiednia "maszyna stanów" i voila.. świat stoi otworem :)

    0
  • #13 12 Maj 2014 18:03
    Badmaneq
    Poziom 23  

    Oczywiście, że wiem lecz kolega mariuszterba na razie nie piszę programu wielozadaniowego. Pewnie jeżeli będzie chciał procesy, wielozadonowość skorzysta z jakiegoś gotowca np. FreeRTOS...

    0
  • #14 06 Cze 2014 21:05
    mariuszterba
    Poziom 10  

    Dziękuje wszystkim za pomoc.
    Umiem już sam napisać opóźnienie, jeszcze nie najlepiej opanowałem przerwania lecz jestem na dobrej drodze :)

    0