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

[ATMEGA8][C/ECLIPSE] - DS1820 i współpraca z wyswietlaczem LED

krdwx 17 Sie 2012 17:06 1917 10
REKLAMA
  • #1 11218846
    krdwx
    Poziom 9  
    Witam.
    Mam problem z prawidłową współpracą wyświetlacza 7 segmentowego i termometru ds1820. Mój problem wygląda tak:
    W pętli głównej podczas wywołania funkcji z biblioteki obsługującej termometr search_sensors() lub odczytania wyniku pomiaru DS18X20_read_meas(...) następuje szybkie, niewielkie mignięcie wyświetlacza. Po usunięciu tych wywołań tych funkcji wyświetlacz działa, tak jak trzeba. Wyświetlacz jest on multipleksowany. Domyślam się, że te funkcje trwają zby długo, jednak nie mam pojęcia jak wyeliminować ten mankament.
    Kod mojego programu:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Proszę na przyszłość używać tagu [syntax=C] do wklejania kodu...[/syntax].
    Poprawiłem, LordBlick
  • REKLAMA
  • #2 11218998
    mickpr
    Poziom 39  
    Oprzyj multipleksowanie o timery, a te niech wywołują przerwania..

    Tworzysz sobie procedurę przerwania od timera.
    Następnie w tej procedurze realizujesz funkcję "przełączania" segmentów.
    Uruchamiasz timer z żądaną częstotliwością + odblokowujesz odpowiednie przerwanie.
  • REKLAMA
  • #3 11219316
    krdwx
    Poziom 9  
    Zrobiłem tak, ale wyświetlacz strasznie migocze, nawet przy TCNT0 = 254
    @Edit
    Funkcja dualLed_show(uint8_t) przebiega nastepująco: wyłącza wszystkie segmenty i anody, jeśli nieparzyste wywołanie przygotuj katody cyfry 1 i załącz anode 1, jeśli parzyste to przygotuj katody cyfry 2 i załącz anode 2.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #4 11219342
    mickpr
    Poziom 39  
    Popraw cytowanie (wybierz syntax=c ) kodu w jednym i drugim przykładzie - nie można za .... żadne skarby się rozczytać.
    A już kompletnie nie wiem co robią twoje przerwania:

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

    zmniejsza zmienne,
    zaś
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    wpisuje w kółko do zmiennej wartość true, tylko po co?

    A gdzie multipleksowanie?
  • REKLAMA
  • #5 11219374
    krdwx
    Poziom 9  
    Pierwsze zmniejsza wartości timerów programowych: http://pl.wikipedia.org/wiki/Round_robin

    Drugi - zgodnie z zaleceniem - ustawia flagę multipleksowania. W pętli głównej jest sprawdzana i wywoływana jest funkcja odpowiedzialna za multipleksowanie.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #6 11219396
    mickpr
    Poziom 39  
    Bez obrazy, ale paskudnie umieszczasz kod.
    krdwx napisał:
    W pętli głównej jest sprawdzana i wywoływana jest funkcja odpowiedzialna za multipleksowanie.
    I to jest powód migania.
    Po to proponowałem ci umieszczenie multipleksowania w timerze, aby przełączanie było co stały okres czasu (w przerwaniu). Miałbyś więc jednakowe miganie - dla "za wolnego timera" lub brak - dla "odpowiedniego timera".
    Ponieważ twojego kodu nie rozumiem, więc wyłączę się z dyskusji.
  • #7 11219425
    krdwx
    Poziom 9  
    Testowałem już to wcześniej, na samym początku. Umieszczenie tej instrukcji w przerwaniu daje ten sam efekt, więc z całym szacunkiem, ale takie zgadywanie nic nie wnosi do dyskusji.
  • #8 11219443
    mickpr
    Poziom 39  
    krdwx napisał:
    Umieszczenie tej instrukcji w przerwaniu daje ten sam efekt, więc z całym szacunkiem, ale takie zgadywanie nic nie wnosi do dyskusji.

    Zgadywanie zostawiam innym..
    A teraz wytłumacz wszystkim, którzy robią multipleksowanie za pomocą przerwań timera, jak wielki popełniają błąd.
  • #9 11219461
    krdwx
    Poziom 9  
    Zaraz zaraz, a ja za pomocą czego robię przerwania? Przez INT0 ?
    Czyli jak ma to wyglądać? Proszę o kawałek kodu, bo chyba się nie rozumiemy
  • Pomocny post
    #10 11219536
    mickpr
    Poziom 39  
    Proszę bardzo:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Przerwanie powinno działać z dobraną częstotliwością.
    Wyłączanie poprzedniego wyświetlacza powinno następować albo razem, albo wcześniej niż włączanie kolejnego.
    Osobiście nie stosuje wyświetlaczy multipleksowanych, a używam w tym celu SAA1064 (zajmuje mi 2 piny na MCU).

    Tematów o multipleksowaniu led jest na tym forum... policzmy: 122.
  • #11 11219602
    krdwx
    Poziom 9  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


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


    Funkcja show_digit(char*) zapala odpowiednie segmenty. Makro OFF_ALL wyłącza wszystko.

    Spróbowałem jeszcze tak: w przerwaniu TIMERA1 wstawiłem te funkcję od multipleksowania, a Round Robina obsługuję w TIMER0 i wszystko działa jak należy. Nie wiem dlaczego, ale TIMER0 jest dobrze ustawiony:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dziękuje i pozdrawiam.

    Nie działało jak należy, ale dlaczego? Przecież przerwania nie mają priorytetów...
    Zwyczajnie TCNT0 w przerwaniu nie był ustawiany, więc zliczało od 0.
REKLAMA