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.

atmel studio M8 C - DS18B20 timingi rklibavr zmienne

Jarosław J 17 Lis 2012 19:22 1704 9
  • #1 17 Lis 2012 19:22
    Jarosław J
    Poziom 14  

    Chcę odczytać Atmegą 8 temperaturę z dwóch czujników DS 18B20, podpiętych do dwóch portów. Program piszę w Atmel Studio Zrodziło się wiele pytań z tym związanych między innymi na temat timingów zmiennych itp. Bardzo proszę życzliwych i doświadczonych o pomoc:

    1. Czy właściwym będzie użycie jednego z przerwań do odmierzenia tych mikrosekund?, nie widziałem w żadnym przykładzie takiego rozwiązania Dla czego?
    2. Dla czego tak naprawdę standardowe funkcje _delay_us() nie nadają się do tego? Dla czego one nie są dokładne?
    3. Widziałem rozwiązania z zastosowaniem bibliotek RKlibAVR Dla czego one są lepsze od tych z WinAVR? czy będą lepsze od wyliczonych opóźnień na podstawie przerwań?
    4. Widziałem rozwiązania gdzie do przepisania temperatury odczytanej używano zmiennej typu FLOAT. Wiem że operacje na niej są czasochłonne jednak wydaje mi się że łatwiej na niej wykonywać różne operacje np porównania z innymi liczbami. (na przykład tworząc termostat) Czy na przykład w układzie termostatu zastosowanie FLOAT'ów nie będzie barbarzyństwem?

    0 9
  • #2 17 Lis 2012 21:21
    tmf
    Moderator Mikrokontrolery Projektowanie

    ad 1. Nie nadają się. Policz ile instrukcji MCU wykonuje w czasie 1-3 us, a następnie ile trwa wykonanie przerwania i obsługa handlera. Zamiast przerwań stosuje się interfejs USART - można nim precyzyjnie i sprzętowo odmierzać czas.
    ad 2. Są dokładne i jak najbardziej nadają się. Zakłądając oczywiście, że procek nie jest taktowany np. 1MHz.
    ad 3. Nie znam tej biblioteki.
    ad 4. float w tym celu to naprawdę głupi pomysł. I zmartwię cię - float do porównań zupełnie się nie nadaje, ba, np. operatora == w ogóle nie powinno się z float używać. Tu masz trochę jak się ich pozbyć:
    http://mikrokontrolery.blogspot.com/2011/04/temperatura-wyswietlacz-konwersja.html

    0
  • #3 18 Lis 2012 00:16
    mirekk36
    Poziom 42  

    1. bo są w tym przypadku do odmierzania zbyt małe czasy a funkcje _delay_us() bardzo dobrze tu się sprawdzają

    2. jak wyżej, właśnie do obsługi 1wire bardzo dobrze się sprawdzają, i nawet jak byś uparł się na zastosowanie do tego UART'a (chociaż szkoda marnować w takim procku uart do takiego celu) .... to i tak musiałbyś z tych funkcji opóźniających korzystać

    3. a dlaczego z kolei wg ciebie RKlibAVR są jakieś super ? To są już trochę stare biblioteki, prace nad nimi dawno już się zatrzymały i na dzień dzisiejszy zawierają wiele błędów niestety

    4. w zdecydowanej większości aplikacji do takich procków używanie floatów to barbarzyństwo a w szczególności do tak prostych operacji, gdzie pozbycie się ich jest proste i banalne. Pomyśl, czym się różni liczba np 22.75 od 2275 ??? tym, że ta druga to pierwsza tyle że pomnożona x100 prawda ? I w ten prosty sposób pozbywamy się floatów. A gdy otrzymasz gotowy wynik np 1745 i wiesz że wcześniej mnożyłeś x100 to teraz podziel przez 100 i masz wartość przed przecinkiem, a z uzyskaniem tego co po przecinku też nie będziesz miał już chyba dalej problemu ?

    poza tym jak już robisz czujniki 1wire to skorzystaj z zalet tej magistrali i nie rób barbarzyństwa ;) polegającego na tym że każdy czujnik na oddzielnym pinie ... a po co ??? od tego jest 1wire ;) więc wykorzystaj i podłącz je na 1 pinie, nawet więcej niż 2

    poniżej przykład tego, że można za skorzystać z pełnym powodzeniem z bibliotek do 1wire korzystających z _delay_us() bez żadnego uszczerbku dla działania programu a nawet innych jego modułów - nawet takich jak wyświetlanie multipleksowane, które nie ucierpi w żaden sposób na tym - dlatego ja, UART'a to poświęciłbym do tego celu na SAMYM końcu jakbym już był pewien, że rzeczywiście go do niczego innego nie wykorzystam:

    http://mirekk36.blogspot.com/2011/09/fakty-i-mity-nt-rzekomych-problemow-z.html

    0
  • #4 18 Lis 2012 08:47
    Jarosław J
    Poziom 14  

    Bardzo się cieszę, że znaleźliście chwilkę czasu na te w sumie proste pytania.

    Układ który chcę zrobić będzie pełnił funkcję wyłącznie termostatu dwukanałowego i mógłbym wykorzystać UART do odmierzania czasu ale tą banalna przyczyną dla której zostanę przy _delayach jest brak wiedzy jak się do tego zabrać.

    Mój projekt będzie zasilany wewnętrznym oscylatorem 8MHz więc jak zrozumiałem mogę zastosować polecenia _delay_ms. Oczywiście jak też zrozumiałem czas 750ms między konwersjami można w tym przypadku odmierzyć Timerem. Nie chodzi o dokładność odstępu ale o blokowanie programu przez _delay.


    Co do dwóch pinów - w tym prostym układzie nie będzie problemu żeby pozwolić sobie na taką rozrzutność. W układzie pozostają jeszcze dwa piny wolne, a ja wolę mieć pewność, że po wymianie czujnika będzie on w tej samej kolejności odczytywany. Wiem, że można to rozwiązać przy pomocy choćby pamięci eeprom, jednak jak już wcześniej napisałem, przenoszę się z Bascoma, i jednak decydującym okazuje się brak tej fachowej wiedzy.

    0
  • #5 18 Lis 2012 09:40
    mirekk36
    Poziom 42  

    Jarosław J napisał:

    Układ który chcę zrobić będzie pełnił funkcję wyłącznie termostatu dwukanałowego i mógłbym wykorzystać UART do odmierzania czasu ale tą banalna przyczyną dla której zostanę przy _delayach jest brak wiedzy jak się do tego zabrać.

    Jeśli idzie tylko o brak wiedzy a mógłbyś sobie pozwolić na wykorzystanie UARTA w tym celu, to masz to dokładnie opisane w książce tmf'a, zawsze można po nią sięgnąć.

    Jarosław J napisał:
    Mój projekt będzie zasilany wewnętrznym oscylatorem 8MHz więc jak zrozumiałem mogę zastosować polecenia _delay_ms. Oczywiście jak też zrozumiałem czas 750ms między konwersjami można w tym przypadku odmierzyć Timerem. Nie chodzi o dokładność odstępu ale o blokowanie programu przez _delay.

    Oj tak, w tym przypadku 750ms strasznie blokowałoby program :(

    0
  • #6 18 Lis 2012 17:11
    Jarosław J
    Poziom 14  

    Jeszcze jedno pytanie: Jeśli odczytana z ds'a wartość będzie zmienną typu double np. 2234 a program obsługi wyświetlacza pozwala mi na wyświetlenie zmiennej typu char, czy jest możliwość żeby odczytaną temperaturę bez używania sprintf 'a zamienić na 22.34? Użycie sprintf'a znów doprowadzi nas do kolosalnego wzrostu kodu.

    0
  • #7 18 Lis 2012 17:57
    tmf
    Moderator Mikrokontrolery Projektowanie

    Zastanów się - odczytana z DS18B20 wartość nie jest typu double. Więc nie twórz problemów na siłę. Potraktuj ją tak jak ci to opisał kolega Mirek w poście #3, punkt 4.

    0
  • #8 18 Lis 2012 20:02
    Jarosław J
    Poziom 14  

    Nie do końca rozumiem!

    Pobrane z Ds'a dane są zapisane w tablicy:
    unsigned char ds18b20_pad[9]

    Trochę niżej składam to i dzielę na 16 czego wynikiem jest zmienna temp zadeklarowana oryginalnie jako double:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zmienna temp była typu "double" i program działał, natomiast zmieniłem ją
    na "char" i po przekształceniach poleceniem sprintf.... mam zero. W sumie nie było to potrzebne, ale chciałem sprawdzić.

    Jeśli chcę wyświetlić zmienną temp zadeklarowaną jako char bezpośrednio wysyłając ją do funkcji wyświetlającej na LCD - nie wyświetla mi jej

    W jaki sposób dane odebrane z DSa przekształcić na dane typu char
    do LCD używam bibliotek Radzia, gdzie funkcja wpisująca tekst żąda zmiennej typu char

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Poniżej mój program:



    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  Szukaj w 5mln produktów