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.

[Atmega8][C] - Włączanie i wyłączanie timera

Atlantis86 11 Lis 2012 19:13 1653 4
  • #1 11 Lis 2012 19:13
    Atlantis86
    Poziom 19  

    Jestem obecnie w trakcie nauki programowania AVR-ów w języku C. Jednocześnie składam w kawałki kod, który mam zamiar wykorzystać w moim pierwszym, poważniejszym projekcie z tej dziedziny. W tej chwili jednak pojawiła się pewna wątpliwość, której nie rozwiała lektura kilku tutoriali.

    Mianowicie w jednym miejscu muszę zmierzyć czas, jaki upłynął od ostatniej ingerencji użytkownika. Jeśli ten nie wykona żadnej akcji przez 4-5 sekund, program ma zakończyć aktualnie wykonywane zadanie, opuszczając pętlę. Mam zamiar użyć do tego timera0. Tylko teraz zastanawiam się w jaki sposób najlepiej go włączać i wyłączać w odpowiednich miejscach programu.

    Do głowy przychodzą mi dwie możliwości:
    1) Poprzez zabawę rejestrami, raz za razem zmieniając tryb pracy timera.
    2) Zastosować zmienną globalną typu char, pełniącą funkcję flagi. Wtedy po prostu w podprogramie obsługi przerwania umieszczę instrukcję warunkową, zwiększającą wartość zmiennej zliczającej przerwania o 1 tylko wtedy, gdy flaga będzie aktywna.

    Co o tym sądzicie? Które rozwiązanie jest bardziej dopuszczalne?

    0 4
  • #2 11 Lis 2012 19:45
    tmf
    Moderator Mikrokontrolery Projektowanie

    To zależy od konstrukcji reszty programu. Nie ma jedynie słusznych i najlepszych rozwiązań. Ja być timer włączał i wyłączał po prostu w kodzie. Rozwiązanie z flaga też jest ok, tylko wtedy nie do końca wykorzystujesz sprzęt - po co inkrementować zmienną skoro masz licznik timera.

    0
  • #3 15 Lis 2012 18:53
    Atlantis86
    Poziom 19  

    Jednak po chwili zastanowienia nieco uprościłem sprawę. Teraz czas jest liczony normalnie - w głównej pętli funkcji, poprzez zastosowanie _delay_ms() i zmiennej zwiększanej o jeden. Przekroczenie pewnej wartości przerywa pętlę, powodując zakończenie działania funkcji. Żeby wprowadzić takie rozwiązanie musiałem tylko minimalnie zmienić kod. Na timer0 uparłem się chyba tylko ze względów dydaktycznych, ale chyba lepiej trzymać się zasady "keep it simple". Na przetestowanie timerów w praktyce jeszcze przyjdzie czas.

    Teraz jestem przy obsłudze rs232 i o ile samo zagadnienie wysyłania znaków nie stwarza dla mnie problemów, to inna kwestia jest dla mnie zagadką.

    Mianowicie trafiłem na TAKI oto tutorial.

    Ktoś może mi wyjaśnić o co chodzi z tym "const char *s "? Wszystkie lekcje, jakie przerobiłem do tej pory, traktowały ciągi znaków jako tabele i w ten sposób należało przekazywać je do funkcji. Czyżby była jakaś inna szkoła?

    I jeszcze jedno. Dobrze rozumiem, że dozwolone jest stosowanie instrukcji zmienna++ np. w argumencie funkcji albo indeksie tabeli? Czy dobrze rozumiem, że taka konstrukcja dopiero po wykorzystaniu zmiennej w charakterze indeksu zwiększy ją o 1? Działa to tak samo, jak w przypadku standardowego przypisywania wartości innej zmiennej (np. a=b++, kiedy wartość b zostanie zwiększona dopiero po uprzednim skopiowaniu jej do a)?

    0
  • #4 17 Lis 2012 10:14
    McMonster
    Poziom 32  

    Atlantis86 napisał:
    (...) Mianowicie trafiłem na TAKI oto tutorial.
    Ktoś może mi wyjaśnić o co chodzi z tym "const char *s "? Wszystkie lekcje, jakie przerobiłem do tej pory, traktowały ciągi znaków jako tabele i w ten sposób należało przekazywać je do funkcji. Czyżby była jakaś inna szkoła?


    Sprawa jest prosta, wymaga jedynie wiedzy o tym, czym są wskaźniki, a to można sobie doczytać. Tablica w C jest w rzeczywistości wskaźnikiem na pierwszy jej element. Czyli mając tablicę char[] jest to analogiczne do char *. Słowo kluczowe const w argumencie znaczy tyle, że funkcja nie może modyfikować zawartości tablicy. Wpływa to na sposób kompilacji i umożliwia w pewnym stopniu kontrolę błędów (kompilator nie pozwoli nam zmodyfikować zmiennej).
    Cytat:
    I jeszcze jedno. Dobrze rozumiem, że dozwolone jest stosowanie instrukcji zmienna++ np. w argumencie funkcji albo indeksie tabeli? Czy dobrze rozumiem, że taka konstrukcja dopiero po wykorzystaniu zmiennej w charakterze indeksu zwiększy ją o 1? Działa to tak samo, jak w przypadku standardowego przypisywania wartości innej zmiennej (np. a=b++, kiedy wartość b zostanie zwiększona dopiero po uprzednim skopiowaniu jej do a)?


    Tak, jest to dozwolone w C. Trzeba tylko bardzo uważać, z której strony wstawia się operator ++ lub --.

    0
  • #5 23 Lis 2012 18:48
    Atlantis86
    Poziom 19  

    Bardzo dziękuję za informację. Mam jeszcze jedno pytanie, związane z tym tematem. Dla większej jasności zamieszczam fragment kodu (tylko ta część, które jest tut istotna).

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Myślę, że procedura w takiej formie jest względnie przejrzysta. Główna pętla while ma wykonywać się dopóki przycisk przycisk PIN nie zostanie wciśnięty po raz dwudziesty pierwszy. Dodatkowo jego pierwsze wciśnięcie aktywuje timer, zliczający kolejne iteracje pętli. Kolejne wciśnięcie PIN zeruje licznik. Moim założeniem było, żeby pętla została przerwana po czterech sekundach bezczynności użytkownika (250*16 ms). Na próbę dałem właśnie taką wartość, pomijając na razie czas potrzebny na sprawdzanie innych warunków podczas każdego wykonania pętli. Niestety trochę się przeliczyłem, bo w praktyce wyszło trochę więcej.

    Tak więc moje podstawowe pytanie brzmi:

    Czy można w jakiś sposób oszacować czas potrzebny na wykonanie pozostałych instrukcji, abym mógł dobrać odpowiednią przerwę po instrukcji timer++?
    Mikrosterownik jest taktowany zegarem 8 MHz.

    Aktywowanie PIN_BREAK oczywiście powoduje natychmiastowe opuszczenie pętli,a tym samym zakończenie procedury.

    0