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

[ATMega162][Bascom]Odczyt z 1wire w przerwaniu.

sundayman 22 Kwi 2010 19:08 4500 34
REKLAMA
  • #1 7992044
    sundayman
    Poziom 26  
    Mam tutaj na Atmedze162 taki problem.

    Zrobiłem odczyt z DS18B20, wykorzystując taką funkcję :

    
    Function Ds_read(byref Sensor As Byte) As Integer
    1wreset
    1wwrite &H55
    1wwrite Sensor , 8
    1wwrite &HBE
    Ds_val = 1wread(2)
    Ds_val = Ds_val * 10
    Ds_val = Ds_val / 16
    Ds_read = Ds_val
    End Function
    


    i wszystko jest ok, o ile wykonuję pomiar wywołując tą funkcję z pętli do...loop w normalnym programie.
    Ale chciałem przenieść wykonywanie pomiaru do przerwania, i zaczęły się schody.
    Ogólnie, przeniosłem do przerwania (timer0) całą procedurę odczytu, w tym wywołanie funkcji. I ku mojemu zaskoczeniu nie działa.
    Najpierw myślałem, że problem jest w przekazywaniu parametrów z/do funkcji pod przerwaniem. ALe potem przeniosłem całą procedurę odczytu do przerwania ;

    
    ' PRZERWANIE /////////////////////////////////////////////////////////////////////
    Przerwanie:
    Disable Timer0
    
    ' miganie ledem
    Incr Czas
    If Czas = Tempo Then
       Toggle Led_online
       Czas = 0
    End If
    
    'pomiar temperatury
    If Ds_count > 0 Then
    
       1wreset
       1wwrite &HCC
       1wwrite &H44
       Wait 2
    
       ' to zamiast funkcji
    1wreset
    1wwrite &H55
    1wwrite Ds_id1(1) , 8
    1wwrite &HBE
    Ds_val = 1wread(2)
    Ds_val = Ds_val * 10
    Ds_val = Ds_val / 16
    
    Print "wynik=" ; Ds_val
    
    End If
    Enable Timer0
    Return
    ' KONIEC PRZERWANIA //////////////////////////////////////////////////////////////
    


    przy czym:
    DS_count to liczba czujników wykryta wcześniej (w tym przypadku=1)
    DS_ID1 to identyfikator czujnika

    I teraz jest tak, że przy pierwszym wywołaniu przerwania ds_val zawiera prawidłowy pomiar , a następne są już równe 0.

    Na początku obsługi przerwania timer0 jest wyłączany, na końcu włączany.
    "Normalny" program nic nie robi (pusta pętla do...loop), żeby nie byłą wątpliwości, że coś tam miesza.

    W czym może być problem ?

    Poprawiłem tytuł.
    [zumek]
  • REKLAMA
  • #2 7997378
    jousto
    Poziom 17  
    Nie wiem jak wyliczasz DS_count ale na moje oko to właśnie problem pojawia się, że za następnymi wywołaniami przerwania właśnie DS_count jest różne od 1 i pomiar nie jest dokonywany.
    Poza tym nie wiem jak to ma działać, analizując po kolei to co robi funkacja w przerwaniu.
    1. Reset
    2. Skip ROM
    3. Polecenie konwersji
    4. Czekaj 2sek
    5. Reset
    i tu zaczyna się coś dziwnego:
    najpierw funkcja działa tak jakby na magistrali był tylko jeden czujnik, a teraz jakby ich było więcej. Musisz być konsekwentny jak korzystaz z funkcji Skip ROM to nie przeskakuj na Match ROM, niby nie ma różnicy ale pewnie nie działa.

    6. Match ROM
    7. Zaadresuj czujnik
    8. Polecenie odczytu scratchpad
    9. Odczyt 2 pierwszych bajtów
    itd

    Po mojemu ta funkcja mogłaby wyglądać tak:

    
      1wreset
      1wwrite &HCC
      1wwrite &H44
      Waitms 200    'w zależności od wybranej rozdzielczości, tu 9bit
      1wreset
      1wwrite &HCC
      1wwrite &HBE
    
      Lsb = 1wread():
      Msb = 1wread():
      Ds_val = Msb * 256
      Ds_val = Ds_val + Lsb 
      Ds_val = Ds_val / 16 
    
      Print "wynik=" ; Ds_val
      
  • #3 7997767
    piotr5000
    Poziom 21  
    Nigdy w przerwaniu nie użyłem "wait" i nie użyje.
  • #4 7997809
    netsecurite.pl
    Poziom 13  
    piotr5000 napisał:
    Nigdy w przerwaniu nie użyłem "wait" i nie użyje.


    Od tego są timery w AVR aby z nich korzystać ;)
  • #5 7997817
    janbernat
    Poziom 38  
    Miałem coś podobnego ale tylko dla 1 DS:
    https://www.elektroda.pl/rtvforum/topic1623781.html
    Dla większej ilości jeszcze nie obliczyłem i nie sprawdziłem.
    Ostatni program jest dobry i działa- przerwanie co 4ms.
    Może spróbuj iść w tym kierunku- ale czas odczytu DS sprawdzałem na oscyloskopie- dla większej ilości DS- trzeba sprawdzić.
  • #6 7997926
    piotr5000
    Poziom 21  
    netsecurite.pl - czytaj uważnie . Nie napisałem , że nie korzystam z timer'ów , ale jaki jest sans obsługi przerwania przez 2 sekundy (WAIT 2) gdy timer wywołuje przerwanie co np. 2milisekundy ?
  • REKLAMA
  • #7 7998003
    mirekk36
    Poziom 42  
    W ogóle gigantycznym nieporozumieniem jest próba "gadania" z czujnikami DSxxxx w przerwaniach. Jak zwykle pojawia się temat flagi, którą wystarczy ustawiać w przerwaniu a w pętli głównej korzystać z tej flagi i co odpowiedni interwał czasowy "prowadzić" rozmowę z czujnikami - inaczej to bez sensu.

    A już nie wspomnę jak niektórzy mówili żeby do przerwania wstawiać choćby Waitms - to już jest masakra ;)
  • #8 7998206
    janbernat
    Poziom 38  
    Bo są timery sprzętowe- i dobrze że są.
    A z nich można zrobić przerwania programowe- wystarczy obliczyć ile razy timer sprzętowy się odezwie.
    A wstawianie Waitms albo _delay w przerwaniu- to jak napisał mirekk36- masakra.
    Ale wstawianie tego w główną pętlę- też.
  • #9 7998430
    sundayman
    Poziom 26  
    hmm... przyznam, że opierałem się na przykładach, które znalazłem tutaj, i prawdę mówiąc, z braku czasu nie zagłębiałem się w protokół 1wire, dlatego pewnie wyszły mi głupoty. Oczywiście, funkcja powinna odczytywać temperaturę z termometru o zadanym DS_id.

    Co do przerwania - pomyślałem o tym , ponieważ w głównym programie korzystam z input na Rs232, no i program mi się zatrzymuje. A chciałem, żeby wyniki pomiarów były "gotowe" do przesłania via RS.

    Zatem, jak powinna ta funkcja wyglądać, zakładając że ma mi pobrać temperaturę z czujnika numerze DS_ID ?
  • #10 7998479
    asembler
    Poziom 32  
    mirekk36 napisał:
    W ogóle gigantycznym nieporozumieniem jest próba "gadania" z czujnikami DSxxxx w przerwaniach. Jak zwykle pojawia się temat flagi, którą wystarczy ustawiać w przerwaniu a w pętli głównej korzystać z tej flagi i co odpowiedni interwał czasowy "prowadzić" rozmowę z czujnikami - inaczej to bez sensu.

    A już nie wspomnę jak niektórzy mówili żeby do przerwania wstawiać choćby Waitms - to już jest masakra ;)


    A ja znowu nie wyobrazam sobie tego abym muial angazowac program głowny który przewaznie słuzy w innym celu jak tylko pomiar temp. W przerwaniu to wychodzi elegancko a ilosc czujników jak moze byc obsłuzona jest dowolna. W programie głownym umieszczam tylko procedure odczytu uzyskanych wartosci z przerwan i ewentualne sprawdzenie CRC co zajmuje ułamiki msek. Dodatkowo sprawa siekomplikuje gdy mamy zasialnie dwuprzewodowe to i tak trzeba zastosowac jakis timer bo nie wyobrazam sobie aby czekac na odczyt ponad 750mS
  • REKLAMA
  • #11 7998542
    mirekk36
    Poziom 42  
    asembler napisał:

    A ja znowu nie wyobrazam sobie tego abym muial angazowac program głowny który przewaznie słuzy w innym celu jak tylko pomiar temp. W przerwaniu to wychodzi elegancko a ilosc czujników jak moze byc obsłuzona jest dowolna. W programie głownym umieszczam tylko procedure odczytu uzyskanych wartosci z przerwan i ewentualne sprawdzenie CRC co zajmuje ułamiki msek. Dodatkowo sprawa siekomplikuje gdy mamy zasialnie dwuprzewodowe to i tak trzeba zastosowac jakis timer bo nie wyobrazam sobie aby czekac na odczyt ponad 750mS


    Asmbler - no panie kochany, sam nick i wypowiedzi na temat tego jak to lubisz asmblera powodowały u mnie wrażenie, że bardzo sprawnie się poruszasz w oprogramowaniu, tymczasem jakieś herezje tu kolega wypisuje.

    Ja obsługuję czujniki DSxxxx czy to w trypie Parasite czy w normalnym 3-żyłowym , obojętnie czy jeden czy całe stado. Dodatkowo wykonuję tysiąc innych rzeczy w tym samym czasie i jeszcze nigdy nie się nic nie komplikowało przez to. Pisanie programu głównego w przerwaniu..... hmmmm czasem się stosuje, gdy np robimy pilota na podczerień, który jedyną rzeczą jaką ma robić to emitować kody.

    Ale pisanie obsługi jakichkolwiek czujników a w tym szczególnie DSxxxx to nieporozumienie, no chyba, że tak jak piszesz znowu twój procek nic nie robi poza pomiarami. Ale to nie opowiadaj o tym, że to normalna praktyka i to jeszcze w asemblerze. Bo to jest raczej stawianie sprawy do góry nogami i niestety jednak trochę pachnie brakiem zrozumienia działania przerwań.

    Myślałem, że ktoś dobrze znający asembler nie ma problemu z implementacją tzw timerów programowych, zdarzeń itp..... aczkolwiek rozumiem dobrze, że pisanie czegoś takiego w samym asm to męczarnia. Warto panie kolego pomyśleć w końcu o C ;)

    Żeby nie być gołosłownym, bierzesz sobie jeden timer sprzętowy i przeznaczasz go na obsługę tzw "tyknięć" systemowych z jakąś stałą częstotliwością np 100Hz. A w oparciu o to w pętli głównej robisz sobie programowe timere i to tyle ile ci się żywnie spodoba. Dzięki temu w pętli głównej nie musisz UŻYĆ ani jednego polecenia jak Wait czy Waitms w Bascomie. W ogóle takie opóźnienia są niepotrzebne - wszystko z dużą prcecyzją odmierzasz timerami programowymi w tym twoje nieszczęsne 750ms.
  • #12 7998577
    asembler
    Poziom 32  
    No cóż moj sposob pomiaru wcale nie angazuje calego procesora bo własnie po to napisałem to w przerwaniu że tak było wygodniej juz nie wiek kiedy tak to musialem rozwiazac ale skoro tak zrobilem to pewnie tak musialo byc (dawne czasy) Według mnie zaleta jest takze to ze moge w dowolnej chwili zawiesic odczyt z DS co np przy programowym generowaniu np dzwieków na głosnik mialo znaczenie. Faktem jest jak ktos wykorzystuje procesor w 10% to najlepiej to zrobic w programie głownym. Co by nie mówic ja pozostane przy swoim rozwiazanu a spierac mie mozna na kazdy temat jak co lepiej napisac.
  • #13 7998717
    sundayman
    Poziom 26  
    koledzy, zlitujcie się :)
    Zamiast dyskutować akademicko, może byście poratowali po prostu
    prawidłową funkcją :)

    Pewnie,że sam powinienem się wgryźć w ten 1wire, ale nie mam teraz czasu na to. Przejrzałem wszystko co się dało znaleźć na elektrodzie, i nie znalazłem łopatologicznego wyjaśnienia, dlatego po prostu zrobiłem jak mi się wydawało ok.
    No ale w tych przerwaniach nie działa i tyle.

    Jak kolega napisał wcześniej, zapodałem tam najpierw polecenia pominięcia adresu (chyba?), potem podania tego adresu - czyli bez sensu. Powiedzcie proszę, jak to powino wyglądać poprawnie ?
  • #14 7998762
    asembler
    Poziom 32  
    Przeciez ci radzimy (no moze nie ja) zebys nie robił tego w przerwaniach a szczegolnie w ten sposób. Przerwania stosuje sie dla zaoszczedzenia czasu procesora, a czy to ma sens w BASIC-u to nie sądze.
  • #15 7998963
    sundayman
    Poziom 26  
    No ale pisałem, że chodzi o to, że główny program korzysta z komendy input, która odbiera polecenia via RS232. I w tym czasie nie ma możliwości "równoległego" odczytu z termometrów. A chodzi mi o to, żeby po odebraniu zapytania o temperatury pomiary były już "gotowe", co można zrobić tylko odczytując je w przerwaniu.

    Jest tylko kwestia prawidłowej obsługi 1wire, przy założeniu, że chcę odczytać konkretny układ, podając adres w zmiennej DS_ID. I to wszystko.
    Czyli - jaka powinna być sekwencja odczytu ? Nie znam poleceń, które wykonują układy DS, i te przykładowe "1wwrite &HCC" mi nic nie mówi...
  • #16 7999001
    asembler
    Poziom 32  
    No to raczej odwróc założenia gdzyz bardziej prawidłowo bedzie jak umiescisz transmisje szeregową w przerwaniu a DS włozysz w główny program
  • #17 7999077
    sundayman
    Poziom 26  
    Człowieku... :)
    Nie musi być bardziej prawidłowo :) Ma działać.
    Cały program jest gotowy. Pominąłem odczyt DSów w przerwaniach, bo nie działało, i zrobiłem po prostu, po zapytaniu przez RS. I tak może być.

    Trzeci raz piszę, że odczytuję komendy z RS poprzez input. No przecież to nie będzie działać w przerwaniu. A przerabianie tego na jakieś inne procedury to jest dopiero sięganie lewą reką do prawego ucha...


    Wolałbym mieć odczytane w przerwaniu. Ale przerabianie programu, który jest ok, jest bez sensu. Dla mnie nie jest istotne ideologiczne "uzasadnienie" czy w przerwaniu jest cacy czy be. Odczyt w przerwaniu załatwia moje potrzeby i to wszystko. Jeśli to jest możliwe (technicznie, że tak powiem) to ok. Jeśli nie, to trudno.

    Przypuszczam, że do tego celu wystarczy prawidłowa sekwencja odczytu.
    Jeśli z jakiegoś powodu bascomowa procedura odczytu 1wire nie działa w przerwaniu, to trudno, zostanie tak jak jest.
  • #18 7999114
    asembler
    Poziom 32  
    Technicznie jest mozliwe przynajmniej w ASM a ty zeby to zrobic w bascomie to nie ma rady musisz sie zapoznac z protokołwem 1-wire ktory nawiasem mowiac jest prosry ja (1 -wir)
    J
  • #19 7999128
    janbernat
    Poziom 38  
    Czy to jest przerwanie czy odwołanie się do podprogramu?
    Jeśli przerwanie- to jakie zdarzenie je wywołuje?
    Po co w przerwaniu- jeśli jest to przerwanie- blokujesz przerwanie od przepełnienia Timera?
    Przecież i tak jest zablokowane.
    Funkcja jest zdeklarowana?
  • #20 7999192
    sundayman
    Poziom 26  
    Mówimy cały czas o przerwaniu z timer0, ustawionym na jak najdłuższy czas (1024).
    Samo przerwanie działa ok, i funkcja, którą skąd zapożyczyłem też działa ok, o ile jest wywoływana nie z przerwania a z głównego programu. Funkcja jest oczywiście zadeklarowana.

    A po co blokuję przerwania ? No widocznie bez sensu, na wszelki wypadek, bo nie wiedziałem, czy nie nastąpi kolejne wywołanie (no ale jak rozumiem, nie).
    Ale to przecież nie jest powodem problemu z odczytem chyba.
  • #21 7999208
    asembler
    Poziom 32  
    Jezeli ty chcesz całą procedure odzcytu z DS-a zmiescic w jednym przerwaniu to to jest bez sensu bo to tak jakbys umiescil odczyt w programie głownym. Tu nie ma zadnego zysku ani czasowego ani tez innego. Jesli tak zrobisz to jest wysoce prawdopodone ze wypadna ci bajty odbierane po rs-sie.
  • #22 7999251
    janbernat
    Poziom 38  
    no to tak:
    Przerwanie od timer0 jest wywoływane zbyt często- podaj jaki jest zegar.
    W przerwaniu robisz tak- incr temp_0.
    I tylko to- nic więcej.
    A w pętli głównej:
    if temp_0>=x then 'tak aby było > niż 750ms
    temperatura=funkcja()
    temp_0=0
    end if
  • REKLAMA
  • #23 7999375
    utak3r
    Poziom 25  
    Powiem tak: obsługa przerwania powinna trwać tak krótko, jak to tylko możliwe. Np. ustawianie jakichś flag, zliczanie wartości itp. Komunikacja z użyciem jakiegokolwiek protokołu ciężko podchodzi pod tę zasadę... Niby działa - ale stwarza ogromne problemy.
    A już użycie "wait"... jak wspomniał kolega - to jest "no no". Tego się nie powinno robić.
  • #24 7999808
    sundayman
    Poziom 26  
    Heh, no już się powtarzam... :)

    W głównej pętli programu jest instrukcja ;

    Input Rs_data

    Czyli, że nic mi nie pomoże żadne odliczanie czasu, bo przez 99% czasu program nic nie robi stojąc na instrukcji input, i czekając na dane z rs232.
    I właśnie dlatego wymyśliłem to przerwanie, żeby - kiedy przyjdzie zapytanie o temperaturę, były te dane już gotowe.
    Skoro zaś nie można tego zrobić w przerwaniu, to musi być tak jak jest, czyli PO odebraniu tego zapytania.

    Tak, że zostawmy to już, bo skoro nie można w przerwaniu odczytać danych z DS, to sprawa nie ma sensu :)
  • #25 7999876
    utak3r
    Poziom 25  
    Powiem więcej - zauważyłem, że DS odpytywany co chwilę, lubi zwracać jakieś idiotyczne wyniki, z kosmosu wzięte. Tak że lepiej jest, jak odpytujemy go tylko na żądanie :)
  • #26 7999900
    mirekk36
    Poziom 42  
    sundayman --> poczytaj sobie o poleceniu Ischarwaiting to sprawa nabierze sensu, poobserwuj inne programy, idź dalej do przodu - bo wszystko da radę zrobić - i to nie w przerwaniu i wcale nie trzeba czekać na INPUT ;)

    utak3r --> skoro DS zwraca wyniki z kosmosu wzięte to świadczy tylko o jednym, że jest źle oprogramowany a nie że to jest kwestią jakichś obserwacji itp. Wszystko da się zrobić żeby było normalnie z odczytami i to nawet bardzo szybkimi. Ale trzeba też co nieco o sprawdzaniu sum kontrolnych poczytać no i prawidłowo soft napisać - wtedy wszystko będzie zawsze działać dobrze tak jak powinno.
  • #27 7999996
    janbernat
    Poziom 38  
    Odpytywanie pojedynczego DS trwa ok. 3.5ms.
    Jeśli w tym czasie przyjdzie przerwanie to pokaże błędny odczyt.
    Taki odczyt można pominąć sprawdzaniem CRC - jak napisał mirekk36.
    Po odczycie ustawiamy DS na pomiar i sprawdzamy wynik np. po 1s.
    Po odczycie mamy prawie 1s na wysłanie danych przez RS.
  • #28 8000043
    mirekk36
    Poziom 42  
    janbernat --> jak się napisze własną procedurę obsługi DS'a to może sobie przychodzić przerwanie w trakcie odczytu "do" czy też odczytu "z" .... a i tak nic się nie stanie ;). Tyle że trzeba w najbardziej krytycznych momentach wyłączać przerwania. Wtedy czasy wyłączenia przerwań są drastycznie krótsze niż taki kawał czasu jak 3,5ms - przecież to "wieczność". W bascomie o tyle kiepsko to się sprawdza, że właśnie można co najwyżej wyłączać przerwania na czas całej procedury odczytu/zapisu, która trwa długo i przez to może przeszkadzać w pracy innym przerwaniom - wtedy kicha :(
  • #29 8000484
    janbernat
    Poziom 38  
    mirekk36- wiem że bascom jest wolny.
    Ale DS też.
    Sam reset to jest 2x480us- prawie 1ms.
    Przesyłanie 64 bitów adresu- 120usx64 =7680us czyli 7.7ms minimum.
    Pomiędzy tymi komendami można włączać przerwania- ale w trakcie chyba nie.
    A odczyt można zrobić potem- ale to też ponad 1ms.
    Tak że nie wiem jak to robisz.
  • #30 8000670
    mirekk36
    Poziom 42  
    janbernat --> Wystarczy przerwania wyłączać na czas przesyłania poszczególnych bitów w odpowiednich pętlach, które wysyłają całość. Pewnie, że to też co nieco zabiera ale o niebo krócej niż gdy wyłączać przerwania na całe te czasy które tu przytoczyłeś.

    Druga sprawa to oczywiście jak się wykorzystuje w ogóle przerwania, bo jeśli w tym sposobie o którym piszę napisałbym jakieś procedury obsługi przerwań jak co niektórzy, gdzie wrzuciłbym polecenia Wait czy Waitms to ten sposób też byłby do kitu.

    Koniec końców, i w takim sposobie jak ja opisuję mogą się co jakiś czas pojawić zakłócenia jednak - to nie uniknione , ale ........... no ale wtedy za każdym razem sprawdza się jeszcze CRC co w 100% eliminuje przykry efekt jak wyświetlanie "wyników z kosmosu"
REKLAMA