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

Dioda nie zmienia stanu co 1s - AVR, timer, bit, C++

yahman 10 Mar 2012 15:47 3521 31
REKLAMA
  • #1 10658604
    yahman
    Poziom 16  
    Witam

    Czy jakaś dobra dusza może mi wskazać błąd w programie? Zamiar był taki żeby dioda zmieniała stan co 1s. Wiem, że to można inaczej zrobić przez przerwania, ale aktualnie zależy mi na takim rozwiązaniu


    Kod: text
    Zaloguj się, aby zobaczyć kod



    Aktualnie dioda się pali stałym światełkiem :/
  • REKLAMA
  • #2 10658647
    sulfur
    Poziom 24  
    yahman napisał:
    while (cnt>3);
    W tym kodzie ten warunek zawsze jest fałszywy.
  • #3 10658667
    yahman
    Poziom 16  
    Dobra dzięki, człowiek czasem się zatnie i terzba go jakoś popchnąć.
  • #4 10658706
    sulfur
    Poziom 24  
    Pomijam już bezsens tego sprawdzenia bitu. Zauważ, że pętla do while wykonuje się, gdy cnt jest większe od 3, ale co najmniej jeden raz. Wykona się zatem jeden raz. Zamień znak większości na znak mniejszości. Jak zacznie działać mniej więcej tak jak oczekujesz zastanów się, jak to zrobić porządnie, żeby nie powiedzieć poprawnie.
  • #5 10658737
    yahman
    Poziom 16  
    jak już poprawiłem w poście wyżej, zlokalizowałem głupi błąd. Ale piszesz "bezsens tego sprawdzenia bitu", możesz więc podpowiedzieć jak to zrobić poprawniej ?

    Czy np. bit_is_set ?
  • REKLAMA
  • #7 10658825
    dondu
    Moderator na urlopie...
    Co ma za zadanie tej fragment kodu:

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

    Co chciałeś osiągnąć?

    Poza tym, skoro już wykorzystujesz flagę przerwania TIFR, to wykorzystaj istotę przerwań do końca.
  • #8 10658841
    sulfur
    Poziom 24  
    dondu w tym konkretnym zastosowaniu nie używanie przerwania jest mądrzejsze. Podkreślam konkretnym. TIFR to jest rejestr, a nie flaga.
  • #9 10658864
    dondu
    Moderator na urlopie...
    sulfur napisał:
    dondu w tym konkretnym zastosowaniu nie używanie przerwania jest mądrzejsze.

    Mądrzejsze? :)
    Sądząc po opisanym problemie, autor tematu jest na bardzo wczesnym etapie nauki C i mikrokontrolerów i wpędza się w technikę, która nie przynosi dobrych doświadczeń. Dlatego uważam, że powinien nauczyć się obsługi przerwania "po bożemu".
  • #10 10658887
    sulfur
    Poziom 24  
    Tak. Autor tematu używa timera do generowania opóźnienia. I nie użycie do tego celu przerwania jest bardzo rozsądne. Jak go zmusisz do użycia przerwania, to następny temat będzie o tym, że program się zawiesza (brak volatile) - bo i tak w przerwaniu ustawiałby flagę, tyle że w pamięci, a nie rejestrze.
  • #11 10658897
    yahman
    Poziom 16  
    Chciałem osiągnąć zmianę stanu diody co 1s, nie potrzebuję jak na razie przerwania, a chciałem wykorzystać tylko flagę przepełnienia TOV0 żeby równo odmierzać czas.

    Trochę poprawiłem warunki, ale program znowu stanął:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #12 10658905
    dondu
    Moderator na urlopie...
    sulfur napisał:
    Tak. Autor tematu używa timera do generowania opóźnienia. I nie użycie do tego celu przerwania jest bardzo rozsądne. Jak go zmusisz do użycia przerwania, to następny temat będzie o tym, że program się zawiesza (brak volatile) - bo i tak w przerwaniu ustawiałby flagę, tyle że w pamięci, a nie rejestrze.

    Z całym szacunkiem, ale co Ty piszesz?
    Przecież właśnie tego wszystkiego powinien się nauczyć.

    Ty chcesz go uczyć, by cały czas młotkiem operował, niezależnie od tego, czy ma wbić gwóźdź, czy rozwalić stary wieżowiec. Nie tędy droga.

    @yahman
    Zaglądnij tutaj: http://mikrokontrolery.blogspot.com/2011/03/led-sterowany-przez-timer.html
  • #13 10658928
    sulfur
    Poziom 24  
    Nie zrozumiałeś mnie. Miganie diodą to nie jedyna sytuacja, w której konieczne jest generowanie opóźnienia. A w niektórych sytuacjach czekanie jest lepsze. Przecież wiesz.
  • #14 10658931
    gaskoin
    Poziom 38  
    sulfur przesadzasz. To, że ktoś zaczyna nie oznacza, że ma pisać programy byle jak, "bo zaczyna", a najlepiej niech ściągnie gotowce, albo jeszcze lepiej niech w ogóle się za to nie zabiera bo jeszcze coś popsuje. Komuś kto będzie zaczynał z czymś bardziej zaawansowanym też będziesz mówił żeby nie używał przerwań bo jest początkujący i na pewno mu nie wyjdzie i niech się borok męczy?
  • #15 10658942
    yahman
    Poziom 16  
    Na tym przykładzie
    http://mikrokontrolery.blogspot.com/2011/03/led-sterowany-przez-timer.html
    opieram naukę, rozumiem co się dzieje w tych przykładach, ale docelowo w programie będę musiał wyliczać prędkość więc będę musiał przerwanie wywoływać szybciej. Największy problem mam jak na razie z wyłuskiwaniem stanów poszczególnych bitów w rejestrze. (wystawiać już umiem).

    Np nie do końca rozumiem jak działa if(TIFR & (1<<TOV0)) robimy AND z xxxxxxx1 i 0000000 wychodzi nam 00000001 ale if nie potrzebuje zero- jedynkowego warunku ?

    no i coś tu jeszcze nie działa:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #16 10658971
    dondu
    Moderator na urlopie...
    sulfur napisał:
    Nie zrozumiałeś mnie. Miganie diodą to nie jedyna sytuacja, w której konieczne jest generowanie opóźnienia.

    Oczywiście program można napisać na wiele sposobów i ważne jest jedynie to, by działał prawidłowo.

    sulfur napisał:
    A w niektórych sytuacjach czekanie jest lepsze. Przecież wiesz.

    Nie, nie jest lepsze, ponieważ nie uczy tak istotnego podejścia jakim jest wykorzystanie sprzętu i minimalizowanie potrzebnej mocy obliczeniowej. Gdy się tego uczy od początku, to później nie ma problemów z wielkimi programami, na małych mikrokontrolerach.

    Dodatkowo oczekiwanie które proponujesz nie pozwala na oszczędzanie baterii poprzez usypiania mikrokontrolera, co tym bardziej przemawia za uczeniem wykorzystania przerwań, a nie techniki pulling-u.

    Pisałem o tym niedawno tutaj: https://www.elektroda.pl/rtvforum/topic2242553.html

    yahman napisał:
    ... ale docelowo w programie będę musiał wyliczać prędkość więc będę musiał przerwanie wywoływać szybciej.

    To znaczy, że w zależności jaką dokładność chcesz osiągnąć, zabierasz się do sprawy z niewłaściwej strony. Od pomiaru czasu trwania impulsów jest Capture Mode. Napisz coś więcej o projekcie.

    Poza tym, stając w pętli nie możesz realizować innych czynności, co niechybnie w przyszłości okaże się nie do zaakceptowania.
  • #17 10658979
    yahman
    Poziom 16  
    nie chce mierzyć czasu trwania impulsu tylko czas pomiędzy 2 impulsami. Rozumiem, że można wykorzystywać przerwania od timera. Ale teraz chciałbym się nauczyć wyłuskiwać bity. Oraz dowiedzieć się czemu ten fragment kodu jest zły ?
  • REKLAMA
  • #18 10658982
    sulfur
    Poziom 24  
    Nie przesadzam. Po prostu nie rozumiecie moich intencji. Nie jest znana mi osoba, która podczas inicjalizacji LCD na HD44780 do generowania opóźnienia stosuje przerwania (od timera). Napiszecie, że AVR ma _delay_ms i _delay_us. No ma, ale ARMy już nie. Całą Twoją wycieczkę w moją stronę gaskoin puszczę mimo uszu.
  • #19 10659024
    dondu
    Moderator na urlopie...
    yahman napisał:
    nie chce mierzyć czasu trwania impulsu tylko czas pomiędzy 2 impulsami.

    I właśnie od tego jest ten tryb.

    yahman napisał:
    Ale teraz chciałbym się nauczyć wyłuskiwać bity. Oraz dowiedzieć się czemu ten fragment kodu jest zły ?

    OK, to także warto znać.

    Twoim problemem jest sposób gaszenia flagi TOV0. Jest tutaj wyjątek opisany w pułapce nr 1: http://mikrokontrolery.blogspot.com/2011/04/avr-czyhajace-pulapki.html
    Gdybyś to robił w przerwaniu, to flaga byłaby zerowana sprzętowo :)
  • #20 10659079
    yahman
    Poziom 16  
    no ale w DTR jest napisane: TOV0 - Flaga przepełnienia licznika 0.
    Bit TOV0 jest ustawiony gdy nastąpi przepełnienie licznika TCNT0. Flaga jest
    sprzętowo kasowana przez wykonywanie kodu obsługi przerwania, albo moŜe
    być kasowana programowo przez wpisanie 0

    Natomiast zerowanie przez 1 jest dla OCF0, którego nie wykorzystuje?

    wpisałem coś takiego:

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


    i program ruszył, ale dlaczego to działa skoro w tym momencie "TIFR &= ~(1<<TOV0);" bit OCF0 jest zerowany przez jedynkę. A skoro jest zerowany przez jedynkę to jest ustawiany przez zero ?
  • #22 10659101
    sulfur
    Poziom 24  
    Dokumentacja techniczno-ruchowa.
  • #23 10659107
    dondu
    Moderator na urlopie...
    Która - pokaż ją - pokaż link.

    EDIT
    yahman napisał:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    i program ruszył, ale dlaczego to działa skoro w tym momencie "TIFR &= ~(1<<TOV0);" bit OCF0 jest zerowany przez jedynkę. A skoro jest zerowany przez jedynkę to jest ustawiany przez zero ?

    Dlaczego edytujesz posty zniekształcając kolejność dyskusji?
  • #24 10659115
    sulfur
    Poziom 24  
    Zapewne ma na myśli Datasheeta.
  • #26 10659123
    gaskoin
    Poziom 38  
    Nie robię wycieczek w Twoją stronę sulfur. Tylko lepiej pokazać jak ma być zrobione, a nie jak będzie łątwiej.

    Chyba jesteś w błędzie :)
    Cytat:
    The bit TOV0 is set (one) when an overflow occurs in Timer/Counter0. TOV0 is cleared by hardware when executing the corresponding interrupt Handling Vector. Alternatively, TOV0 is cleared by writing a logic one to the flag


    EDIT: nie odświeżyłem zakładki i odpowiedziałem na posta sprzed 200 lat :)
  • #28 10659135
    yahman
    Poziom 16  
    aha, czyli mam błąd w dokumentacji... PL, sprawdziłem z angielską, jest inaczej.
  • #29 10659146
    gaskoin
    Poziom 38  
    To co masz to nie jest dokumentacja tylko jakaś próba przetłumaczenia dokumentacji.
REKLAMA