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

avr atmega32[c] - odliczanie sekundy ,zliczenie 15625 przerwan ?

deywid 19 Sty 2017 00:31 3915 62
  • #1 16210815
    deywid
    Poziom 11  
    witam , przy kwarcu
    #define F_CPU 4000000UL
    timerze0 i preskalerze 1 mam przepelnienie po 256 krokach po czasie 0,000064
    s.
    zliczajac 15625 przerwan powinienem miec sekunde.
    jednak wystepuja u mnie 5 sekund opoznien z kazda kolejna minuta.

    zliczajac w ten sposob popelniam blad ?
  • #2 16210866
    Konto nie istnieje
    Konto nie istnieje  
  • #3 16210947
    BlueDraco
    Specjalista - Mikrokontrolery
    1. Czy masz w tym urządzeniu kwarc 4 MHz?
    2. Nie pokazałeś ani kawałka programu. Nie wiemy nawet, w jakim języku piszesz (chyba w C). Przy takich założeniach musiz zapewnić, że:
    - przerwanie timera obsłużysz w max. 256 cyklach
    - żadne inne przerwanie nie spowoduje opóźnienia obsługi timera, ktre mogłoby skutować zgubieniem przerwania

    Takie parametry, jakie przyjąłeś, są na granicy możliwości AVR - to będzie działało tylko w szczególnych warunkach.
  • #4 16211065
    kamyczek
    Poziom 38  
    do skasowania
  • #5 16211098
    BlueDraco
    Specjalista - Mikrokontrolery
    kamyczek: tego nie wiemy, bo nie widzimy kodu. Na zdrowy rozsądek timer powinien działać ciągle, również w czasie obsługi przerwania.
  • #6 16211151
    Konto nie istnieje
    Konto nie istnieje  
  • #7 16211307
    kamyczek
    Poziom 38  
    do skasowania
  • #8 16211339
    Konto nie istnieje
    Konto nie istnieje  
  • #9 16212233
    deywid
    Poziom 11  
    wewn kwarc 4Mhz, (fusebit C3, D9).
    jezyk C.

    w przerwaniu jest tylko zliczanie czasu.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    w jaki sposob okreslic jakie mam opoznienie zwiazane z kodem i wywolaniem przerwania ??
    odpalam debug i odmierzam czas miedzy kolejnymi wywolaniami linii przepelnienia = 0; , wychodzi kolo 0,22 s i uwzgledniam to pozniej w tym ifie
    if(przepelnienia == (15625 - 3437) )
    ni jak ma sie to rzeczywistosci niestety.
    projekt mam z optymalizacja - level O1
  • #10 16212277
    grko
    Poziom 33  
    No jeżeli przerwanie masz co 640us oraz masz błąd około 8%. Jest to na oko 50us. Przy 4Mhz odpowiada do 200 cyklom. Biorąc pod uwagę jak masz napisane przerwanie to całkiem możliwe, że to właśnie z tego powodu masz opóźnienia. Przypisanie TCNT0 = 0 na końcu przerwania a nie na początku, również nie pomaga.
  • #11 16212298
    Konto nie istnieje
    Konto nie istnieje  
  • #12 16212312
    BlueDraco
    Specjalista - Mikrokontrolery
    Instrukcja TCNT = 0 jest zbędna i fałszuje pomiar czasu. Wyrzuć ją z obsługi przerwania, a zostanie Ci tylko błąd oscylatora.

    Nie masz żadnego "wewnętrznego kwarcu", bo niczego takiego nie ma w mikrokontrolerze - używasz niedokładnego oscylatora RC.

    Ponadto bezsensownie sprawdzasz wartość min, gdy wiadomo, że nie mogła się zmienić. Zagnieźdź if () jeden w drugim- sprawdzaj minuty tylko przy zmianie sekund, a godziny tylko przy zmianie minut.
  • #13 16212318
    Konto nie istnieje
    Konto nie istnieje  
  • #14 16212338
    grko
    Poziom 33  
    @Piotrus_999 Nie wiem. Nie jestem mistrzem AVR tak jak ty i nie znam na pamięć rejestrologi AVR. Jak coś wiesz to napisz wprost i nie spamuj tematu, zwłaszcza, że BD już o tym napisał.
  • #15 16212375
    Konto nie istnieje
    Konto nie istnieje  
  • #16 16212390
    grko
    Poziom 33  
    @Piotrus_999 Nie wiem jaki jest cel Twoich 2 ostatnich postów. Ani nie wnoszą nic do tematu ani nie byłeś pierwszy ze wskazaniem mojego błędu bo BD wszystko wyjaśnił. Próbuj dalej.
  • #18 16213792
    kamyczek
    Poziom 38  
    do skasowania
  • #19 16213828
    Konto nie istnieje
    Konto nie istnieje  
  • #20 16214577
    BlueDraco
    Specjalista - Mikrokontrolery
    Kamyczku, pokazałeś błędny kod i udzieliłeś błędnych rad. Nie wpuszczaj człowoeka w maliny. Odejmowanie 15625 od 15625 nie ma sensu - szybciej podstawić zero. Twierdzenie, że w przerwaniu nie należy wykonywać prostej i szybkiej czynności, jaką jest zliczania czasu, i że w programie musi istnieć jakaś kompletnie zbędna "pętla główna" - to propagowanie niczym nie uzasadnionych zabobonów.
  • #21 16214612
    deywid
    Poziom 11  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    i nadal mam straty ok 3 sekundy na minute (tzn o 3 sek za duzo na minute).
  • #22 16214614
    grko
    Poziom 33  
    A nie lepiej po prostu inkrementować jedną zmienną w przerwaniu. Przykładowo ilość sekund. Bo rozumiem, że ten timer ma służyć do odmierzania timeoutów a nie pełnić funkcje zegarka.


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Następnie zaimpementuj sobie funkcje do konwersji sekund na dd:hh:mm:ss

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Konwesji oraz wyświetlania dokonujesz tylko wtedy kiedy potrzebujesz (podpowiem, wtedy gdy zmieni się wartość seconds)
  • #23 16214655
    BlueDraco
    Specjalista - Mikrokontrolery
    grko napisał:
    Następnie zaimpementuj sobie funkcje do konwersji sekund na dd:mm:ss

    ... która, z powodu wykonywanych przez nią dzieleń, będzei się wykonywać kilkadziesiąt lub kilkaset razy wolniej, niż kolejna inkrementacja sekund, minut i godzin.

    No po prostu inwazja ekspertów z dobrymi radami... ;)

    Opóźnienie bierze się na 99% z błędu częstotliwości zegara uC, a nieznaczne (zbędne) przyspieszenie działania programu można byłoby uzyskać odliczająć przepełnienia od 15625 w dół, zamiast od 0 w górę.
  • #24 16214660
    grko
    Poziom 33  
    @BlueDraco Konwersja potrzebna jest raz na sekundę. Istny performance killer. Nie wspominam już, ne na chwilę obecną jest delay_ms(100) w main loop. Dodam jeszcze, że kod typu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    jest po prostu badziewiasty (nie obraź się autorze;)). No ale jak już szukamy mikroptymalizacji to najlepiej aby zmienne były 8 bitowe. No i post-inkermentacje koniecznie należy zmienić na pre-inkrementacje.
  • #25 16214692
    BlueDraco
    Specjalista - Mikrokontrolery
    Inkrementacja sekund potrzebna jest raz na sekundę, minut raz na minutę, godzin raz na godzinę, a żadna nie wymaga dzielenia, które trwa min. kilkadziesiąt cykli, a które w Twoim rozwiązaniu MUSI wykonywać się co sekundę, zresztą 2 razy. Optymalizacja jak.... ;)

    ALe racja, tu się uC nie przepracuje, już bardziej na wyświetlaniu, w tym na zbędnym ustawianiu kursora na pozycji, na której już jest.

    Za to jedyne, co można poprawić w kodzie, który skrytykowałeś jako "badziewiasty" - to połączenie inkrementacji ze sprawdzeniem warunku.

    if (++sek == 60)

    co i tak niewiele albo i nic nie zmieni w wydajności, ale będzie ładniej i bardziej zwarcie w zapisie.
  • #26 16214706
    grko
    Poziom 33  
    BlueDraco napisał:
    Twoim rozwiązaniu MUSI wykonywać się co sekundę, zresztą 2 razy.


    Rly? So what? Ile to zajmie czasu procesora? 0.1%? Założę się, że obsługa wyświetlacza zajmuje o rząd (albo dwa rzędy) wielkości więcej czasu procesora.
  • #27 16214742
    Konto nie istnieje
    Poziom 1  
  • #28 16214775
    grko
    Poziom 33  
    @drobok Tutaj dochodzimy do sedna problemu:) Autor użył złego timera do tego zadania bo, aby odmierzyć jedną sekundę musi wykonać się 15625 przerwań. No ale to oczywiście nie jest problemem. Problemem jest właściwa inkrementacja i funkcja do konwersji wywoływana raz na sekundę.
  • #29 16214846
    kamyczek
    Poziom 38  
    do skasowania

    Moderowany przez Pawel wawa:

    Do przemyślenia: 3.1.11. Nie wysyłaj wiadomości, które nic nie wnoszą do dyskusji. Wprowadzają w błąd, są niebezpieczne czy nie rozwiązują problemu użytkownika.
    3.1.17. Nie wysyłaj pytań bardzo podstawowych, na które odpowiedzi można znaleźć w instrukcji obsługi lub ogólnie dostępnych źródłach. Nie prezentuj postawy, że mi się należy. Dbaj o poziom pytań i dyskusji. Dziękujemy.
    3.1.9. Nie ironizuj i nie bądź złośliwy w stosunku do drugiej strony dyskusji. Uszanuj odmienne zdanie oraz inne opinie na forum.
    30 dni blokady pisania.

  • #30 16214880
    Konto nie istnieje
    Konto nie istnieje  
REKLAMA