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

BASCOM ATMEGA8 - Multipleksowanie 4 wyświetlaczy, pytanie o przerwania.

rekinisko 12 Lis 2012 23:10 3243 21
  • #1 11522450
    rekinisko
    Poziom 22  
    Witam!
    Ostatnio koledzy pojechali po moim programie do mulitpleksowania wyświetlaczy bez użycia timera to postanowiłem go poprawić bo faktycznie dostrzegłem zalety.
    Nowy program działa, ma w pętli zwiększać o jeden wartość zmiennej "wartosc" i ją wyświetlać. W głównej pętli programu wpisane jest tylko polecenie incr teoretycznie powinien być szybki a ślimaczy się strasznie i wykonuje to polecenie jakieś cztery razy w ciągu sekundy. Wpisanie komendy waitms w główną pętlę kończy się tragedią, wpisanie print dla przykładu kończy się krzakami na wyświetlaczu, zbaraniałem.

    Proszę o odpowiedzi jak dla żółtodzioba i proszę o wykazywanie się cierpliwością bo chciałbym się czegoś nauczyć. Dziękuję z góry.

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #2 11522599
    Mol
    Poziom 30  
    Tyle dowaliłeś programu w przerwaniu , że chyba będzie ślimaczył i timera w takim układzie się raczej nie wyłącza .
  • #3 11523284
    piotrva
    VIP Zasłużony dla elektroda
    Żadnych WAITxx w przerwaniach!! Zapamiętaj sobie tę zasadę na zawsze (a przynajmniej do momentu, w którym będziesz wiedział co robisz)
    Multipleksowanie za pomocą przerwania powinno wyglądać tak:
    0. n jest zmienną globalną, określającą numer wyświetlacza
    1. początek przerwania
    2. wygaszam wszystkie wyświetlacze
    3. wystawiam na port segmentów dane liczby liczba(n)
    4. zapalam wspólne wyprowadzenie wyświetlacza n
    5. zwiększam n, jeśli n>liczby wszystkich wyświetlaczy to resetujemy n
    6. koniec przerwania
    Niech Kolega zaimplementuje to w swoim programie.
    Dalej co do liczb i ich zamiany na to co ma być na LED - najlepiej wyliczać wartości do wystawienia na port segmentów podczas zmiany liczby, a nie przy każdym, odświeżeniu, jak to Kolego robi teraz.
  • #4 11524538
    Procesor32
    Poziom 13  
    Autora wątku odsyłam tutaj Link
  • #5 11525532
    ptero
    Poziom 24  
    Witam.
    Nie używaj lookup. Zrób sobie tablicę cyferka[10], nadaj jej wartości na początku programu i będziesz miał port=cyferka[d]. Wszystkie obliczenia rób poza przerwaniem.
    W przerwaniu tylko wyświetlaj dane na wyświetlaczu. I to tylko jednym naraz.

    Mój przykładowy programik (zegarek z termometrem do motocykla) A1 A2 A3 A4 to zmienne, które program zmienia: temperatura/czas/znak, przerwanie wyświetla je na wyświetlaczu. Co 4 przerwanie wyświetla 1 cyferkę lub literę.
  • #6 11528895
    SylwekK
    Poziom 32  
    Warto wiedzieć, że jeśli pracują przerwania i użyjesz jakiegoś wait w pętli głównej to nigdy nie będzie to "wait" taki o jaki Ci chodziło... przerwania zabierają czas procesorowi i generalnie dłużej mu schodzi ze wszystkim łącznie z odmierzaniem i tak stosunkowo mało dokładnego wait.
  • #7 11529350
    rekinisko
    Poziom 22  
    No niestety to wielka wada tego rozwiązania, że przerwania kradną czas ;/ Teraz widzę, że dodanie opóźnienia nawet waitus 1 wywraca na głowę główną pętle programu. Oto moje wypociny, niestety jeszcze nie spełniłem wszystkich warunków o których wspominaliście. Program obsługuje dwa przyciski w pętli głównej które zwiększają i zmniejszają wartość zmiennej "wartosc". Piszcie co jest źle a ja postaram się poprawić. Lookupa jeszcze zostawiłem, wiem uparty jestem.

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #8 11529599
    ptero
    Poziom 24  
    Witam.
    Zdefiniuj sobie na początku programu tablicę[9] wpisz dane z data i np gdy masz wyświetlić na danej pozycji liczbę 3 to piszesz portd=tablica[3].
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #9 11530274
    Procesor32
    Poziom 13  
    Oj Mamusiu Kochana, Panocku (autor wątku) NIGDY nie robi się multipleksowania na tym samym Timerze, który jest wykorzystany do odmierzania czasu.

    Mega 8 na pewno ma dwa Timery, więc jeden na przerwania związane z czasem oczekiwania klawiszy, natomiast drugi do multipleksacji.
    Nie wyłącza się Timera w pętli głównej.
    Jest on potrzebny.
    Po co Goto w pętli głównej ?
    Po co pętla w pętli głównej ?
    Wiele czasu jeszcze Panockowi pozostało do końca edukacji produktu MS.

    Ponownie odsyłam.
  • #10 11530466
    rekinisko
    Poziom 22  
    Procesor32 napisał:
    NIGDY nie robi się multipleksowania na tym samym Timerze, który jest wykorzystany do odmierzania czasu.

    Zbawco mój :) tergo nikt wcześniej mi nie napisał.

    Procesor32 napisał:
    Nie wyłącza się Timera w pętli głównej.

    No wyłącza się bo inaczej w takim rozwiązaniu jak moje ekran migocze ;) choć chciałbym w końcu tego nie robić i zrozumieć o co kaman.

    Procesor32 napisał:
    Po co Goto w pętli głównej ?

    GOTO w pętli ponieważ to jedyne rozwiązanie dzięki któremu mogłem korzystać z "klawiatury" i ekran nie migał a wartość ulegała płynnej zmianie na wyświetlaczu.

    Procesor32 napisał:
    Po co pętla w pętli głównej ?

    A to to chyba pozostałość przed strachem użycia timera i radzeniem sobie w taki właśnie sposób.

    Teraz jak już znacie mój tok myślenia to przestawcie mnie do dobre tory proszę.
  • #11 11530527
    ptero
    Poziom 24  
    Wywal oba wewnętrzne rozkazy do loop, bo się na nich zatrzymuje gdy masz wciśniety klawisz, chyba dlatego mryga. A tak, doda lub odejmie wartość i pętla główna leci dalej... Niepotrzebne będą goto.
  • #13 11530822
    Konto nie istnieje
    Konto nie istnieje  
  • #14 11530903
    rekinisko
    Poziom 22  
    Saabotaz napisał:
    Rekinisko, to powinno wyglądać tak:
    Kod Basic4GL - [rozwiń]
     
    Wyswietl:
     
    incr n
    if n>4 then n=1
    Portb = Lookup(n , Katody)
    Portd = Lookup(l(n) , Tablica)
     
    Load Timer0 , 125
    Return
     

    No to wiele zmieniło ;) jutro wkleję poprawki do oceny.
  • #15 11531129
    Procesor32
    Poziom 13  
    Zgadzam się z Kolegą Saabotaż.
    Niestety mimo dwukrotnego odesłania autora wątku do innego wątku, gdzie zawarty jest przykład dotyczący tematu wątku nie skorzystał z mojej propozycji.
    W związku z czym zbędnie się męczy.
  • #16 11531417
    SylwekK
    Poziom 32  
    Procesor32 napisał:
    ...NIGDY nie robi się multipleksowania na tym samym Timerze, który jest wykorzystany do odmierzania czasu...

    Procesor32 napisał:
    ...Mega 8 na pewno ma dwa Timery, więc jeden na przerwania związane z czasem oczekiwania klawiszy, natomiast drugi do multipleksacji....


    Hmmm... nie wiem czy dobrze zrozumiałem, ale jeśli się mylę to mnie popraw i wytłumacz dlaczego wszystko działa:
    Bez problemu przy multipleksie w tym samym przerwaniu zamontowane mam timery programowe do odliczania jednostek czasu - w zależności od potrzeb średnio jest ich od 3 do 5. Oprócz tego bez problemu w tym samym przerwaniu czytam np. temperaturę z DS-a, a o innych procedurach (np. sterowanie grupowe), które muszą się w tym przerwaniu razem z wyświetlaczami zmieścić już nie wspomnę. Nic mi nie miga, itp... 8-O
  • #17 11531491
    Konto nie istnieje
    Konto nie istnieje  
  • #18 11531888
    Procesor32
    Poziom 13  
    SylwekK napisał:
    do odliczania jednostek czasu - w zależności od potrzeb średnio jest ich od 3 do 5

    Nie twierdzę, że tak nie można.
    Ale przenieś choć część swoich Sub do przerwania Timer2, lub 1 i zobacz jaka jest różnica w działaniu programu.
  • #19 11532633
    rekinisko
    Poziom 22  
    Procesor32 napisał:
    Ale przenieś choć część swoich Sub do przerwania Timer2, lub 1 i zobacz jaka jest różnica w działaniu programu.

    A różnica jest i to spora, program przyśpiesza znacznie, wczoraj przerobiłem cały program na timer1, skończyły się problemy z komendą wait. Więc jeżeli timer1 jest wolny to będę go bardzo chętnie używał.
  • #20 11533007
    Procesor32
    Poziom 13  
    Cieszy mnie, że kolega czyta z uwagą i wyciąga wnioski z postów.
  • #21 11533104
    SylwekK
    Poziom 32  
    Procesor32 napisał:
    ...Ale przenieś choć część swoich Sub do przerwania Timer2, lub 1 i zobacz jaka jest różnica w działaniu programu.


    Tylko, że ja kompletnie nie widzę takiej potrzeby. Skoro wszystko działa jak należy, program pisany jest modułowo, działanie oparte na programowych timerach, które spokojnie dają radę, przerwania robią to co powinny i jeszcze mam trochę czasu na obijanie się procesora to po co mam korzystać z kolejnego przerwania.To, że procesor ich posiada to nie znaczy, że trzeba bałaganić. Wychodzę z założenia, że program ma korzystać z jednego timera do głównych przerwań czyli wszelkie timery, multipleks, itd., pozostałe w zależności od potrzeb mogą zliczać np. impulsy zewnętrzne czy generować w tym czasie pwm.

    Odnośnie dokładności w odliczaniu przerwania dobrze jest stosować zamiast np.

    Load Timer0, wartość

    taką postać:

    Counter0=Counter0+wartość

    Przeważnie przy większych częstotliwościach będzie widać znaczną poprawę. Po wskoczeniu do przerwań timer zazwyczaj zliczy już parę impulsów, więc, żeby było równo trzeba je zaktualizować z tym co już policzył. Sprawdzone w praktyce. Miałem kiedyś jakieś dziwne interferencje na sterowniku silnika krokowego. Po poprawce tej lini jak ręką odjął :D
  • #22 11533730
    Procesor32
    Poziom 13  
    SylwekK napisał:
    Odnośnie dokładności w odliczaniu przerwania

    Oczywiście, jeśli tak Koledze działa program to spoko.

    SylwekK napisał:
    Odnośnie dokładności w odliczaniu przerwania

    Jeszcze lepiej oprzeć się na rejestrach procka.

    Dodano po 1 [godziny] 8 [minuty]:

    SylwekK napisał:
    działanie oparte na programowych timerach

    O ile zwiększył się kod programu ?
    Jeśli Timera 1 lub 2 nie używamy w ogóle do PWM, lub przerwań to można któregoś z nich spokojnie użyć.
    Z tym, że Timer1 jest 16 bitowy, a 0 i 2 8 bitowe.
REKLAMA