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

[C][Atmega8A] - DS18B20, wyświetlacze 7-osegmentowe, a opóźnienia

Dople 02 Kwi 2013 18:07 2454 23
  • #1 12145004
    Dople
    Poziom 19  
    Sprawa wygląda tak, że siedze nad tym długo, a w Internecie nie znalazłem nic, co by mi pomogło. Szukałem dość dużo i już zaczynam się frustrować.

    Nie chodzi o delay trwający 750ms, bo ten wyeliminowałem. Rzecz jest m.in. w tych, które trwają od kilku do aż 500µs (reset pulse).
    Śmiem przypuszczać, że to właśnie za przyczyną tych krótkich opóźnień wyświetlacze siedmiosegmentowe lekko "drgają" (gasną na bardzo krótko).
    Jeżeli prescaler któregoś z timer-ów ustawię na zbyt niski to na wyświetlaczu zaczynają się pojawiać "bzdury" - myślę, że w jakiś sposób kolidują one z kilkumikrosekundowymi opóźnieniami.

    W przypadku konwersji temperatury (zamiana dwóch bajtów na postać "do wyświetlenia") nie odczułem żadnego problemu: temperatura w pomieszczeniu jest wyświetlana tak, jak należy. Na razie nie zaprzątałem sobie głowy jakimiś większymi zakresami. Nie stosowałem jakichś skomplikowanych metod, więc kompilator nie powinien zrobić z tego jakiegoś "cyrku", mimo, że zrealizowałem to dość "chałupniczo".

    Mam takie pytania:
    1. Czy jest jakaś możliwość realizacji komunikacji z DS18B20, która nie będzie uzależniona od delay-ów?
    2. Czy własne napisanie delay-ów może mi w czymś pomóc?
    3. Jeżeli chciałbym zrealizować coś bardziej skomplikowanego to powinienem "dołożyć" jeszcze jeden µC, żeby uniknąć niespodzianek? Miałoby się to wiązać z przerwaniami zewnętrznymi i paroma innymi rzeczami opartymi o timery.
    4. Czy biblioteka z dallas semiconductors może mi w czymś pomóc?


    DS18B20 nie jest zasilany pasożytniczo, a wyświetlacze siedmiosegmentowe są multipleksowane. Użyłem też ośmiobitowego rejestru przesuwnego w celu "zaoszczędzenia" kilku pinów.
    Fusebity ustawione fabrycznie (taktowanie 1MHz).

    Będę wdzięczny za wszelkie sugestie.


    edit: volatile są w nadmiarze - to chyba nie jest problem?

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #2 12145351
    wdogli
    Poziom 18  
    Witam.
    Proponuję wszystkie operacje przeprowadzić na przerwaniach.
    Czyli na przykład
    Przerwanie od Timer 1 steruje wyświetlaniem znaków co określony czas wyświetlasz kolejny znak czas dobierasz na tyle krótki żeby nie widzieć migotania,
    Przerwaniem od Timer 0 odmierzasz czas dla odczytu temperatury.
    Pozdrawiam
  • Pomocny post
    #3 12145426
    BlueDraco
    Specjalista - Mikrokontrolery
    Napisz wyświetlanie od nowa - w tym kodzie wszystko jest źle. Zdefiniuj obrazy cyfr w postaci tablicy stałych indeksowanej wartością cyfry. Wyrzuć procedury wyświetlania cyfr i switche, które je wywołują - to wszystko razem da się zrobić w jednej linijce kodu, a u Ciebie zajmuje to ponad 120 linii. Wyświetlacz multipleksowany MUSISZ obsługiwać w przerwaniu timera. Niestety, do obsługi OneWire też potrzebujesz przerwania timera (innego), i te dwa przerwania mogą sobie lekko przeszkadzać, więc trzeba je zrobić naprawdę starannie.
  • Pomocny post
    #4 12145435
    tmf
    VIP Zasłużony dla elektroda
    Dople napisał:

    Mam takie pytania:
    1. Czy jest jakaś możliwość realizacji komunikacji z DS18B20, która nie będzie uzależniona od delay-ów?
    2. Czy własne napisanie delay-ów może mi w czymś pomóc?
    3. Jeżeli chciałbym zrealizować coś bardziej skomplikowanego to powinienem "dołożyć" jeszcze jeden µC, żeby uniknąć niespodzianek? Miałoby się to wiązać z przerwaniami zewnętrznymi i paroma innymi rzeczami opartymi o timery.
    4. Czy biblioteka z dallas semiconductors może mi w czymś pomóc?


    ad. 1. Oczywiście, że tak.
    ad. 2. Nie.
    ad. 3. Dziwny pomysł.
    ad. 4. Być może, musiałbyś ją przeanalizować.
    Istotnie obsługa OW w oparciu o delaye to pomysł kiepski, szczególnie, że można ją rozwiązać semisprzętowo przy pomocy USART. W mojej stopce masz link do przykładów (darmowych), tam masz m.in. przykład obsługi OW w oparciu o USART.
  • Pomocny post
    #5 12145450
    piotrva
    VIP Zasłużony dla elektroda
    To chyba jakiś primaaprilisowy spóźniony żart.
    Cały program nadaje się do śmieci:
    1. Wyświetlanie realizujemy w przerwaniu timera, każde przerwanie na jedną cyfrę (cyfry lecą w pętli)
    2. wzory cyfr zapisujemy w tablicy, a nie jako 10 funkcji... To mnie przekonuje do udziału tego kodu w konkursie na najgorszy program roku
    3. Od razu w przerwaniu od odświeżania (nie ma sensu zaprzęgać drugiego timera - to nie musi być stricte 750,000ms) generujesz sobie flagi timingujące co 750-1000ms - po ich wystąpieniu w programie głównym wykonujesz odczyt temperatury, a potem wysyłasz CONVERT_T, żeby za kolejne 750-1000ms móc powtórzyć cykl
    EDIT: @tmf - flagowanie konieczności operacji 1-wire po przerwaniu odświeżania, a następnie w pętli głównej wykonanie tych operacji w dodatku między cli(); i sei(); może spowodować co najwyżej niewidoczne dla oka mignięcie LEDów, nawet jeśli zostawimy te delaye, to sam odczyt jest dosyć krótki, potem przeliczenia mogą być przerywane swobodnie. A istotnie najlepiej OW obsłużyć za pomocą USART, jeśli jest dostępny w danym uC i nie używany do innych celów.
    ---
    Podsumowując, żeby to działało musisz poczytać trochę teorii (na forum i w rozmaitych kursach jest tego już sporo, więc nie będę tego przepisywać), a potem napisać program od zera.
  • #6 12145467
    Dople
    Poziom 19  
    Dziwne, że wcześniej coś mi się całkiem wykrzaczało, kiedy chciałem wyświetlanie przenieść do przerwania. No, nieważne... ^^'

    Muszę powiedzieć, że chyba zyskałem też na jasności świecenia. Tymczasowo zasilam układ z programatora, a to nie jest 5V, a nieco mniej. W sumie to też... nieważne.


    Niestety nadal są widoczne mignięcia mimo, że "wyświetlanie" jest w przerwaniu timera0 bez prescalera.

    Komunikację przez 1-Wire przeniosłem do przerwania Timera 1. Poza ustawieniem bitu CS10 ustawiłem też bit CS11 przez co zmniejszyłem częstotliwość migań... Niestety tylko zmniejszyłem, bo nadal one są.


    --

    Skoro da się zrealizować bez delayów to bardzo dobrze. ^^
    Szukałem informacji nt. UART, ale nie znalazłem nic. Zaraz zapoznam się z materiałem.


    Dziękuję bardzo za pomoc. Tematu na razie nie zamykam - nigdy nic nie wiadomo. :)

    @piotrva - robiłem to wyświetlanie "żeby było". Dzięki za krzepiącą opinię.
    edit: w zasadzie to można ująć "żeby przetestować" działanie. Tak mi było "najszybciej".


    edit2: W gruncie rzeczy najbardziej zależało mi na jakichś informacjach nt. eliminacji delay-ów.
  • #8 12145734
    tmf
    VIP Zasłużony dla elektroda
    Dople napisał:

    Skoro da się zrealizować bez delayów to bardzo dobrze. ^^
    Szukałem informacji nt. UART, ale nie znalazłem nic. Zaraz zapoznam się z materiałem.


    Jak pisałem, w linku z mojej stopki znajdziesz przykłady do ściągnięcia z ftp, tam masz gotowy kod oparty o USART, bez delay (masz też z delay, ale to nie jest dobry pomysł, co już odkryłeś). Delaye i częsta transmisja OW raczej zawsze będzie powodować subtelne zmiany jasności, w sumie 0,5ms blokady przerwań to pominięcie co najmniej jednego cyklu odświeżania LED. Zwykle nie powino to być widoczne, ale przy niewielkiej intensywności świecenia coś tam może się zmienić, co zauważysz. Generalnie blokowanie procka niezależnie od tych LEDów na 0,5ms jest raczej złym stylem programowania i chociażby dla dobra przyszłych projektów warto nauczyć się takie delaye eliminować.
    @piotrva - jeśli brakuje nam USARTów, to znaczy, że wybraliśmy do realizacji danego zadania niewłaściwy procesor. Pomijam, że dla dużej firmy, kryteria są inne, ale dla hobbysty zmiana na procek z 2, 3, czy 8 USARTami to nie koniec świata, a dopłata 1-2 zł dla świętego spokoju jest tego warta.
  • #9 12145754
    snnaap
    Poziom 25  
    Ciekawi mnie sposób sterowania wyświetlaczem przez Autora, czy wyświetlacz podpięty jest do uK za pomocą rejestru szeregowo równoległego?


    co ma robić ta funkcja:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    odczekać 65tys taktów?
  • #10 12145861
    BlueDraco
    Specjalista - Mikrokontrolery
    Ja bym raczej stawiał, że czeka 1 lub 2 obiegi pętli, w zależności od wartości początkowej p. Obieg pętli to popularna jednostka czasu u piszących pierwszy lub drugi program albo pierwszy lub drugi podręcznik programowania mikrokontrolerów w swoim życiu. ;)
  • #11 12145886
    snnaap
    Poziom 25  
    BlueDraco napisał:
    Ja bym raczej stawiał, że czeka 1 lub 2 obiegi pętli, w zależności od wartości początkowej p. Obieg pętli to popularna jednostka czasu u piszących pierwszy lub drugi program albo pierwszy lub drugi podręcznik programowania mikrokontrolerów w swoim życiu. ;)


    Wszystko fajnie z tym, że ja akurat nie doszukałem się wartości początkowej w tym programie oprócz momentu deklaracji zmiennej, chyba że ktoś znalazł :D
    W takim wypadku czas trwania tej funkcji to 65mS przy 1MHz?
    No chyba że się mylę, a jeżeli nie to wyświetlacze odświeżają się 15 razy na sek.
    Oczywiście abstrahując od tego że program ma swoje inne wady.

    Pozdrawiam
  • #12 12145935
    Dople
    Poziom 19  
    @snnaap: Ta funkcja ("ms") to jakaś pozostałość - coś zmieniałem, ale skoro spełniło moje wymagania to już zostawiłem odłogiem.
    Pierwszego pytania nie rozumiem.

    Tu znalazłem jakieś informacje o tym, że można sobie efektywnie poradzić bez UART: http://mirekk36.blogspot.com/2011/09/fakty-i-mity-nt-rzekomych-problemow-z.html
    Nie ma (albo nie "doszukałem się" żadnego kodu).

    @tmf: Znalazłem już te materiały. Chodzi o "1WireUSART.c" i "1wire_basic_uart.c", tak?
    Nad książką się zastanawiałem jakiś czas temu, ale na razie nadal nie mam wystarczających funduszy. :x


    edit: Od początku myślałem, że będzie lepiej będzie poszukać rozwiązania w którym obędę się bez delay-ów, ale chciałem sprawdzić, czy to "ruszy". Chciałem też jakikolwiek "efekt", choćby nie do końca efektywny. ;)
  • #13 12145949
    piotrva
    VIP Zasłużony dla elektroda
    Co do usart masz rację, ale jak mówisz czasem wybór uC dyktują inne niż tylko model - czasem te parę zł robi różnice przy dużych partiach, a zastosowanie softowego 1w nie sprawia problemów.
    Przykład - mój projekt matrycy led - tam narzucilem sobie m8 i nawet z softowym 1w nic nie miga.
  • #14 12145993
    snnaap
    Poziom 25  
    Dople napisał:
    @snnaap: Ta funkcja ("ms") to jakaś pozostałość - coś zmieniałem, ale skoro spełniło moje wymagania to już zostawiłem odłogiem.
    Pierwszego pytania nie rozumiem.


    No to może spytam inaczej, pokaż (lub opisz) jak masz podpięty wyświetlacz do uK.

    Funkcji ms używasz podczas multipleksowania więc raczej ma ona znaczenie przy programie pokazanym w pierwszym poście w szczególności jeżeli wprowadza ona dodatkowe opóźnienie trwające 65 ms :d
  • #15 12146063
    Dople
    Poziom 19  
    Sprawdzałem z różnymi czasami, ale przypuszczam, że musiałbym przebudować kod wg zaleceń, żeby to spełniało swoją funkcję jak należy.
    W każdym razie od "ms" nie zależy miganie wyświetlacza. edit: sprawdziłem to nawet teraz.

    trzy piny podpięte do uC: SCK, RCK, SI, natomiast SCLR do Vcc, a G do masy.
    Piny od QA do QH przez rezystory (w sumie 16 sztuk) do pinów wyświetlaczy (wspólna katoda).

    Datasheet: http://www.datasheetcatalog.com/datasheets_pdf/M/7/4/H/M74HC595B1R.shtml
  • #16 12146077
    BlueDraco
    Specjalista - Mikrokontrolery
    Zmienna bez wartości początkowej w systemach wbudowanych musi być zainicjowana na zero, a warunkiem powtarzania (a nie wyjścia z!) pętli jest wartość równa 1. Czylli - jeden obieg jeśli była różna od zera, dwa obiegi jeśli przed pętlą była równa 0. Funkcja ms() nie czeka więc prawie wcale - jakieś marne mikrosekundy.
  • #17 12146110
    Dople
    Poziom 19  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wyświetla się dobrze poza miganiem powstającym za sprawą delay-ów związanych z 1-wire.
    Może to nie jest poprawny sposób wyświetlania, ale taki sobie po prostu obmyśliłem. Następny kod napiszę zasięgając informacji z "Internetów".
  • #18 12146130
    stanleysts
    Poziom 27  
    Takie delay'e do one-wire? Hm no to powodzenia :D
  • #20 12146231
    Dople
    Poziom 19  
    Już wiem, że jest niepoprawny. Kilka osób już to napisało! W gruncie rzeczy chodziło o sam odczyt temperatury i związane z tym opóźnienia. "Finalny" kod wyświetlania napiszę w oparciu o materiały z Internetu.

    @stanleysts: aha.

    Jeżeli inny sposób (kod) wyświetlania sprawi, że te delaye nie będą miały znaczenia to poproszę o taką informację, a nie jakieś "poszlaki".
  • #21 12146477
    BlueDraco
    Specjalista - Mikrokontrolery
    Przerwanie timera, tablica wartości cyfr do wyświetlenia, tablica obrazów cyfr. W każdym przerwaniu wybierasz cyfrę, pobierasz jej obraz z tablicy i wyrzucasz na wyświetlacz.
  • #22 12146529
    Dople
    Poziom 19  
    I wtedy delay-e od DS18B20 nie będą sprawiać, że będzie migać? Co prawda jest to ledwo zauważalne, ale...
    edit: informacje z artykułu, do którego podałeś link mogą sprawić, że obejdę się bez USART?
  • Pomocny post
    #23 12146579
    BlueDraco
    Specjalista - Mikrokontrolery
    Jeśli w przerwaniu wyświetlania będzie tylko zatrzaśnięcie danych w HC585 i wybór kolumny, to nie ma problemu. Do OW najlepiej jednak będzie użyć UARTa, bo na przerwaniach timera na ATmega raczej się zarżniesz. OW na UART, ładowanie danych wiersza w pętli głównej i jakoś to poleci nawet na cienkim ATmega.
  • #24 12146650
    Dople
    Poziom 19  
    Chodziło mi po głowie by użyć przerwań dla OW, ale - tak jak napisałeś - myślałem, że to będzie mordęga.
    Cóż, przerobię sobie wyświetlanie, a potem "doogarnę" UART/USART na tyle, żeby poradzić sobię z OW.
    Dzięki.
REKLAMA