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.

[M32][Bascom] Prośba o sprawdzenie programu (nie działa) PWM+INT

Antystatyczny 04 Lip 2012 21:43 2029 21
  • #1 04 Lip 2012 21:43
    Antystatyczny
    Poziom 16  

    Witam, napisałem taki oto kod:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Początkowo miałem jedynie regulację jasności świecenia diody poprzez PWM, ale chciałem wyświetlić sobie wartość zmiennej JASNOŚĆ na wyświetlaczu LED. po uruchomieniu timer2 i dopisaniu obsługi program przestał działać... Może którys z kolegów widzi błąd? Obecnie nie mam regulacji świecenia diody i generalnie nic się nie dzieje. Może problem jest w tym, że oba timery pracują z takim samym preskalerem? Nie do końca wiem, czy obsługa PWM potrzebuje przerwań.

    0 21
  • #2 04 Lip 2012 23:44
    FastProject
    Poziom 28  

    Zrób taką konfiguracje timer2: Config Timer2 = Timer , Async = Off , Prescale = 256
    A na początku obsługi przerwanie tego timera: Start Timer2.

    Daj znać co z tego wyszło.

    0
  • #3 05 Lip 2012 00:29
    zumek
    Poziom 39  

    Daro_Elektronik napisał:
    ...Daj znać co z tego wyszło.


    Zapewne guzik z pętelką :D

    Włącz przerwanie.

    0
  • #4 05 Lip 2012 09:16
    Antystatyczny
    Poziom 16  

    Przecież mam włączone przerwanie komendą enable interrupts :)

    0
  • #5 05 Lip 2012 10:12
    MArSTER_1
    Poziom 18  

    Pomiędzy instrukcje:
    On Timer2 Multipleks

    Enable Interrupts
    wstaw instrukcję Start Timer2. Nie na początku przerwania jak napisał daro:"A na początku obsługi przerwanie tego timera: Start Timer2."

    0
  • #6 05 Lip 2012 12:04
    Antystatyczny
    Poziom 16  

    Panowie, przecież w tej konfiguracji timer startuje automatycznie.

    Na potwierdzenie tego, powyżej napisałem, stworzyłem krótki program testowy:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Timer w takiej konfiguracji startuje samodzielnie, ALE! Nie działa przy wykorzystaniu preskalera 256 oraz 1024. Spotkał się ktoś z takim zachowaniem timera2? Sprawdziłem timer0 i timer1, ale one zachowują się normalnie, tzn. pracują z wszystkimi dostępnymi dla nich preskalerami.

    Dodano po 17 [minuty]:

    A polecenie enable timer2 dawałem w pierwszy kod, ale też nie pomagało. Oczywiście wstawiłem to polecenie wedle wskazówki kolegi.

    0
  • #7 05 Lip 2012 12:14
    MArSTER_1
    Poziom 18  

    Odpowiedź jest na stronie 82 i 127 PDF ATmegi 32. Po prostu Timer2 ma inne bity ustawiane dla współczynnika prescale niż Timer0. Jeśli zależy ci na Timer 2 to zaprogramuj fo wpisując wartość bezpośrednio do rejestru sterującego Timerem2 czyli do TCCR2. Dla prescale 1024 trzeba wpisać do rejestru 00000111. Bascom doskonale radzi sobie z takim wpisywaniem.

    0
  • #8 05 Lip 2012 13:04
    Antystatyczny
    Poziom 16  

    Dzięki za podpowiedź. Wystarczy, że napiszę TCCR2 = &B00000111?

    Dodano po 3 [minuty]:

    dodałem następującą linię tuż po poleceniu config timer2:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Timer2 nadal nie chce pracować.

    0
  • #9 05 Lip 2012 13:37
    MArSTER_1
    Poziom 18  

    Instrukcję napisałeś dobrze. Zastępuje ona instrukcję Config Timer2 oraz instrukcję Start Timer2. Usuń instrukcje Config Timer2 oraz Enable Timer2.
    teraz jeszcze trzeba skonfigurować Timer2 do generacji przerwania. Musisz do rejestru TIMSK wpisać bit TOIE2.

    0
  • #10 05 Lip 2012 20:52
    Antystatyczny
    Poziom 16  

    Taki oto kod nie działa:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Szczerze mówiąc nie mam pojęcia dlaczego to nie działa. z preskalerem 128 i mniejszym działa normalnie. Z 256 i większym w ogóle nie włącza się timer2. Nie zmienia się wartość rejestru TCNT2.

    0
  • #11 05 Lip 2012 21:28
    arktik1
    Poziom 27  

    źle:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Powinno być:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    PWM liczy od 0 do 255, jakim cudem ma być mniejsze od 0 lub większe od 255?
    Poza tym spróbuj:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    zmień na to:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    I dalej
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Jak uporasz się z tym, to zajmiemy się wyświetlaniem :D

    Dodano po 1 [minuty]:

    Poza tym czym mniejsze PRESCALE, tym lepsza rozdzielczość.

    Dodano po 2 [minuty]:

    Kurcze i jeszcze wywal DEBOUNCE bo do zwiększenia od 0 do PWM 255 będziesz naciskał 255 razy.

    0
  • #12 05 Lip 2012 21:47
    Antystatyczny
    Poziom 16  

    Nie mam problemu z napisaniem programu do regulacji jasności świecenia diody przy pomocy PWM. Program podstawowy, czyli bez prezentacji zmiennej JASNOSC na wyświetlaczu LED działał i w niczym nie przeszkadzało to, że przez ułamek sekundy w podprogramie zwieksz i mniejsz zmienna ta była poza zakresem, bo natychmiast była korygowana. W ten sposób zapewniłem sobie zapętlenie. Problem pojawił się w momencie, gdy chciałem użyć timer2 z preskalerem 256. Celowo nie chcę korzystać z timer1, bo mam w przyszłości plan, by wykorzystać go do innego zadania :). Tak więc obecnie problem jest taki, że timer2 nie pracuje, nie nalicza taktów gdy jest z preskalerem wiekszym od 128(256 i 1024). Co do debounce... Fakt, muszę 255 razy nacisnąć plus, by uzyskać pełną jasność świecenia. Sugerujesz użycie pętli if then oraz opóźnienia waitms20, a następnie ponowne sprawdzenie odczytu?

    PS. Z multipleksowaniem tez nie mam juz problemu, bo z pomocą kolegów z elektrody zostałem naprowadzony na właściwe tory :)

    0
  • #13 05 Lip 2012 21:59
    arktik1
    Poziom 27  

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    A TIMERY zamień na chwilę, zobacz czy sytuacja się zmieni.

    Dodano po 2 [minuty]:

    Cytat:
    podprogramie zwieksz i mniejsz zmienna ta była poza zakresem

    Nie mogła być bo BYTE liczy od 0 do 255.
    powinno być
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #14 05 Lip 2012 22:06
    Antystatyczny
    Poziom 16  

    Na chwile wgrałem w procek mój starszy program, który działa, a oparty jest o timer2 z preskalerem 256. Poniżej go zaprezentuję w całości.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Proszę o zerknięcie w sekcję konfiguracji timer2. Niczym sie nie rózni od tej, która została uzyta w kodzie w pierwszym poście. Gdzie ja robię błąd, że ten timer nie pracuje? Na timer1 program działa poprawnie, ale widać jakby duchy na wyświetlaczu, bo każda cyfra jest multipleksowana z częstotliwością 122Hz (preskaler 1 przy FOSC 16MHz)

    0
  • #15 05 Lip 2012 22:07
    30402
    Użytkownik usunął konto  
  • #16 05 Lip 2012 22:28
    Antystatyczny
    Poziom 16  

    Ok, skompiluje program z dyrektywą $sim, a nastepnie będę próbował pauzować działanie programu w symulatorze. Program z pierwszego postu testowałem w procku. PWM działa, a multipleks nie, bo timer2 nie raczył ruszyć. Programy testowe sprawdzałem wyłacznie na symulatorze sugerując sie tym, że w przypadku użycia timer0 i timer1 widziałem naliczanie wartości w rejestrach odpowiednich dla każdego z timerów. Jedynie timer2 sprawia mi kłopot z preskalerem 256 i 1024. Własnie dlatego uznałem, że symulator wystarczy mi do rozwiązania problemu timer2
    Dziekuje za podpowiedzi, już sprawdzam

    Dodano po 2 [minuty]:

    Skompilowałem z dyrektywą $sim, pauzowałem program, ale timer2 nie raczył rozpocząć naliczania. Procesor mam sprawny, bo obok klawiatury mam własnie włączony mój moduł uruchomieniowy z wgranym minutnikiem, który odlicza mi teraz czas do zera.

    Dodano po 8 [minuty]:

    Zadeklarowałem jasnosc jako INT, bo na moment może przyjąć wartość -1 oraz 256. Chodziło mi o to, by przy zapętlaniu w obsłudze klawisza plus i minus mieć możliwość sterowania diody z maksymalną i minimalną wartością współczynnika wypełnienia. Gdybym zrobił if jasnosc = 0 then jasnosc = 255, pozbyłbym się możliwości zgaszenia diody. Dlatego własnie na moment jest wartość ujemna.
    Obliczanie wpakuję w program główny, by nie zasmiecac przerwania( cenna wskazówka - dziękuję)

    0
  • #17 05 Lip 2012 22:32
    30402
    Użytkownik usunął konto  
  • #18 06 Lip 2012 00:00
    Antystatyczny
    Poziom 16  

    Zaraz dokonam kilku kosmetycznych zmian i ponownie dodam enable timer2. Dam znać o efektach

    Dodano po 13 [minuty]:

    Do dyspozycji mamy nastepujący kod, który generalnie już działa (z małymi wadami)

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Program realizuje PWM, wyświetla na wyświetlaczu LED informację, ale ta informacja jest uszkodzona, bo nie jest wyświetlana pierwsza cyfra (setki). Wyeliminowałem błąd w połączeniach. Anody są sterowane z portu C (nogi 7-5, z czego noga 7 odpowiada za setki). Nie widzę błędu...
    Aha, cyfra jedności ma spore duchy, to pewnie skutek tego, że setki nie są wyświetlane...

    (mod i dzielenie wywalę do pętli głównej w kolejnej wersji kodu)

    Dodano po 4 [minuty]:

    Czy obecnośc obliczeń w obsłudze przerwania może dawac taki efekt?

    Dodano po 14 [minuty]:

    Kolejna wersja kodu z obliczeniami w pętli głównej. Nie zmieniło to działania całego programu. Ponownie sprawdziłem sprzęt, by się upewnić, że cyfra setek jest sprawna i poprawnie sterowana. Prezentuję kod:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Dodano po 37 [minuty]:

    Przedstawiam w pełni działający kod. Nie wywaliłem debounce, bo nie przeszkadza mi wielokrotne naciskanie klawiszy plus i minus.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Wyświetlanie setek nie działało, bo pętla warunkowa if anoda = 3 then anoda = 0 była na końcu obsługi przerwania. Przeniosłem na początek i wszystko ruszyło jak nalezy. W moim przypadku dzielenie implementowane w przerwaniu nie przeszkadzało, ale pewnie byłoby problemem w przypadku rozbudowanych obliczeń. Nauczyłem się również, że zmienne maja zakres globalny w każdej sekundzie jej istnienia. Nie można dokonywać obliczeń na zmiennych, które bezpośrednio sterują segmentami, bo widać zakłócenia. Bardzo dziekuje za wszystkie podpowiedzi. Do teraz nie wiem, dlaczego nie działał timer2 :)

    Dodano po 14 [minuty]:

    Mam jeszcze jedno pytanie dotyczące obsługi klawiszy.
    Mozna w prosty sposób zrobic tak, by:
    Naciskam klawisz i zmienna się np. zwiększa
    Trzymam klawisz naciśnięty
    jakiś odstęp czasowy, np. sekunda, a potem np. zwiekszamy wartość zmiennej póki klawisz jest przycisnięty.
    puszczamy klawisz i zmienna przestaje być zwiekszana

    0
  • #19 06 Lip 2012 08:08
    arktik1
    Poziom 27  

    Oczywiście że się da tak zrobić.
    Ale nie w taki prosty sposób.
    Trzeba przenieść obsługę ZWIEKSZ i ZMNIEJSZ do pętli głównej i tam uwarunkować przyciskanie klawiszy.
    Do tego trzeba będzie dorobić kilka zmiennych i policzyć czas zwłoki wciśniętego klawisza.
    Przez multipleksowanie raczej nie stosować WAIT itp.

    0
  • #20 07 Lip 2012 22:49
    Antystatyczny
    Poziom 16  

    Dlaczego nie stosować wait? Przecież przerwanie i tak się wykona.

    0
  • #21 08 Lip 2012 18:36
    arktik1
    Poziom 27  

    Cytat:
    Dlaczego nie stosować wait?

    Dlatego, że to strata czasu Uc.
    Na początku swojego programowania też często używałem WAIT.
    Szybko okazało się, że bardziej skomplikowane programy nie mogą z tym pracować.

    0
  • #22 08 Lip 2012 19:15
    30402
    Użytkownik usunął konto