Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

1wire i przerwania. Czy i który timer wykorzystuje 1wire? ATmega32.

plp 08 Apr 2005 15:31 3541 23
  • #1
    plp
    Level 15  
    Czy i który timer wykorzystuje 1wire. Chce wyorzystać jeden timer do cyklicznych przerwań, ale jak wykorzystam timer 0 lub timer 1 wysiada transmisja 1wire.

    Timer2 wykorzystuje zegar czasu rzeczywistego wewnetrzny.

    ATmega32.

    Pozdrawiam !

    PL
  • #2
    LordBlick
    VIP Meritorious for electroda.pl
    plp wrote:
    Czy i który timer wykorzystuje 1wire. Chce wyorzystać jeden timer do cyklicznych przerwań, ale jak wykorzystam timer 0 lub timer 1 wysiada transmisja 1wire.

    ATmega32 nie ma wbudowanego interface 1wire, wiec nie rozumiem problemu, a wróżyc tylko mogę, że o bascom się rozchodzi... Stawiałbym na niezbyt szczęśliwą obsługe przerwań przez Bascom (zapisuje/odczytuje co się da na stosie, co zabiera zbyt dużo czasu w niektórych przypadkach).

    plp wrote:
    Timer2 wykorzystuje zegar czasu rzeczywistego wewnetrzny.

    Nie ma czegoś takiego, Timer2 może (ale nie musi) pracować asynchronicznie z udziałem dodatkowego zewnętrznego oscylatora kwarcowego 32768Hz, nic poza tym. ATmega8/8535/16/32/64/128 ( mające Timer2, możliwe, ze nie wymieniłem wszystkich np. AT908535 też, ale już wycofany z produkcji) nie ma w sobie prawdziwego RTC, tylko na podstawie tego timera mozna zaimplementować programowo RTC.
    Pozdrawiam, Light-I
  • #3
    olekewaagata
    Level 25  
    Przyczyna leży w tym, że jesli w czasie łączności po 1-wire nastapi przerwanie to z racji swojej specyfiki zasadniczy tok programu (a w tym przypadku komunikacja 1-wire) jest zatrzymywana i wykonywana jest procedura przerwania, a po powrocie z przerwania (powrót do 1-wire) transmisja jest już rozsynchronizowana i idzie w krzaki.
    Napisz coś więcej o przerwaniu: czasie trwania, czestotliwość występowania bo jest możliwość wybrnięcia z problemu.
    Możesz też rozwiazać to w najprostrzy ale prymitywny sposób: na czas komunikacji 1-wire zawieszaj wszelkie przerwania, jesli transmisja po 1-wire nie jest często to jest to dobre rozwiązanie. Oczywiście po obsłudze 1-wire nie zapomnij przywrócic zawieszonych przerwań.
  • #4
    plp
    Level 15  
    To fakt, chodzi o program w Bascomie.

    Konkretnie wykorzystuje Bascomowy zegar z kwarcem 32767 Hz, z tego co wiem, pracuje to na Timerz 2.
    Co jedną sekundę odczytuje temperaturę z 4 DS18B20 na jednej magistrali. Nie wiem czy to wykorzystuje timer i który.
    Do tego w przerwaniach wywoływanych przepełnieniem Timera 0 lub 1, które miały występować z częstotliwością ok. 10 kHz, chciałem obserwować przebieg napięcia sieci i we właściwym czasie odliczając liczbę przerwań wyzwalać triak. Co ma działać jak ściemniacz, regulujący obroty silnika.

    Ten sposób regulacji wypróbowałem, tylko bez przerwań i działał. Teraz jak włączałem przewania tiamrów, to wykładał się odczyt temperatury.

    PL
  • #5
    LordBlick
    VIP Meritorious for electroda.pl
    No cóż, nie pozostaje nic innego, jak wywalić konstrukcje typu "waitms", których w tym całym "wspaniałym" środowisku nie brakuje, tak, aby w czasie, gdy czeka na coś, nie mielił bezczynnie, tylko robił coś innego, jeżeli jest do zrobienia.
    Powodzenia, Light-I
  • #6
    zumek
    Level 39  
    No tu już nie mogę zdzierżyć :wink:
    Chcesz korzystać z przerwań od 2 timerów i dziwisz się ,że wchodzą w paradę transmisji 1wire.Te timery to będą nawet sobie wchodzić w paradę , jeśli ich praca nie będzie jakoś zsynchronizowana.Trzeba poprostu "widzieć" oczami wyobraźni pracę programu i tak go skonstruować by działał prawidłowo , lub potrafił się skorygować , tzn. popełniać błędy ale i także je naprawiać , gdy zajdzie taka potrzeba.Nawet pisząc w asm , nie jesteśmy w stanie przewidzieć czy jakieś 2 procedury pracujące w ścisłym reżimie czasu nie wejdą sobie w paradę , a jeśli taka sytuacja się zdaży , to program powinien odpowiednio na to zareagować.Teraz jak zwykle przykładzik :wink:
    ATMega32(moja) pracuje właśnie z kwarcem zegarkowym do synchronizacji zegarka(ajakże) i pomiar temperatury z DS-a(a jakże by inaczej).Kiedy przychodzi pora pogadać z DS-kiem to czytam zawartość licznika timera i jeśli ona nieuchronnie zbliża się do max to sobi czekam aż wykona się przerwani timerka i wtedy wiem ile mam czasu na pogawędkę z DS-em.Można też oczywiście procedury wykonywać w pętli , aż nam się CRC zgodzi ... itd,itp.Ostatecznie możemy dołączyć R/W 1wire do przerwania.Sposobó jest wiele i trzeba brać siły(procka) na zamiary(programisty) :wink:
    Uff...

    Pozdrawiam
    Piotrek
  • #7
    plp
    Level 15  
    Akurat waitms żadnej nie było. Co prawda w tym czasie i tak nic nie robił, ale przynajmniej lalał w kółko.

    Jednym słowem skoro z wykorzystania przerwań w tym przypadku nici, trzbea będzie obsługę "ściemniacza" zrealizować w normalnej częsci kodu naprzemian z resztą funkcji.
    Zapewne można wykorzystać np. 16 bitowy Timer1 jako wskaźnik stabilnego szybkozmieniającego się czasu, żeby nie opierać się na liczeniu wykonanych pętli, bo to może być złudne.

    PL
  • #8
    LordBlick
    VIP Meritorious for electroda.pl
    Jawnie nie ma waitms, ale sporo "funkcji" bascoma potrzebujących na coś poczekać mielą w miejscu. Co do wykorzystania timera jako wskaźnika czasu, to jestem jak najbardziej za, bo sam tak robię w asemblerze - czas minął - rób co trzeba, nie minął - to obleć pozostałe procedury, może której z nich akurat czas minął - czyli w procedurze przerwania mam dla każdej procedury w pętli głównej po liczniku pokazującym czas dla każdej procedury - liczniki pedzą w stronę zera, ale go nie przekraczają, jak licznik równyzero, to procedura się wykonuje i albo resetuje licznik, albo stawia flagę że się już wykonała... ;)
    Pozdrawiam, Light-I
  • #9
    plp
    Level 15  
    Tak, tylko że jak piszesz liczniki lecą Ci w przerwaniu. Ja przerwania nie mogę użyć bo wykłada mi 1wire. Mogę za to obserwować sam wskaźnik Timer1, który leci od 0 do 65535, jeśli się nie mylę i ustawiać w programie wskaźniki przy jakiej wartości Timer1 ma się coś wydarzyć.

    A z tego co widzę to na wewnętrzym RC 8 MHz jest to już tak szybkie, że spokojnie powinno dać radę.

    PL
  • #10
    LordBlick
    VIP Meritorious for electroda.pl
    No cóż, dobrze jest raz napisać własną porządną wersję obsługi 1wire, a potem uzywac wielokrotnie... ;)
    BTW Można używać wiele wektorów przerwań na raz, ważne aby procedury ich obsługi trwały krótko, co w Bascomie wymaga nieraz większej dłubaniny (i wymaga dogłebnej wiedzy o tym co robi kompilator z poszczególnymi poleceniami), niż w asm.
    Pozdrawiam, Light-I
  • #11
    olekewaagata
    Level 25  
    Jeśli będziesz miał przerwanie o czestotliwości 10 kH to nigdy nie uda Ci sie porozmawiac z DS-em. Czasu nie rozciągniesz (he he ). Natomiast przy przerwanich z częstotliwością nie większą niż czas potrzebny na obsługę DS-a zmieścisz się ze wszystkim, tak jak piszą wyżej.
  • #12
    LordBlick
    VIP Meritorious for electroda.pl
    olekewaagata wrote:
    Jeśli będziesz miał przerwanie o czestotliwości 10 kH to nigdy nie uda Ci się porozmawiac z DS-em. Czasu nie rozciągniesz (he he ). Natomiast przy przerwanich z częstotliwością nie większą niż czas potrzebny na obsługę DS-a zmieścisz się ze wszystkim, tak jak piszą wyżej.
    Nie mów nigdy... Kwestia spojrzenia na problem z innej perspektywy. Jeżeli zależności czasowe dla DS-a oprę na tym samym przerwaniu, to nie widze żadnego problemu. Kwestia optymalnego dobrania częstotliwości przerwania. Ale to już raczej inna bajka niż Bascom.
    Light-I
  • #13
    elektryk
    Level 42  
    olekewaagata wrote:
    Jeśli będziesz miał przerwanie o czestotliwości 10 kH to nigdy nie uda Ci się porozmawiac z DS-em. Czasu nie rozciągniesz (he he ).
    To prawda, ale na czas komunikacji z DS można wyłączyć przerwania, przerwania będą obsłużone po ponownym włączeniu.
  • #14
    LordBlick
    VIP Meritorious for electroda.pl
    olekewaagata wrote:
    [...]Możesz też rozwiazać to w najprostrzy ale prymitywny sposób: na czas komunikacji 1-wire zawieszaj wszelkie przerwania, jesli transmisja po 1-wire nie jest często to jest to dobre rozwiązanie. Oczywiście po obsłudze 1-wire nie zapomnij przywrócic zawieszonych przerwań.
    elektryk wrote:
    olekewaagata wrote:
    Jeśli będziesz miał przerwanie o czestotliwości 10 kH to nigdy nie uda Ci się porozmawiac z DS-em. Czasu nie rozciągniesz (he he ).
    To prawda, ale na czas komunikacji z DS można wyłączyć przerwania, przerwania będą obsłużone po ponownym włączeniu.
    To też prawda, ale jak mierzymy z ich pomocą czas, to nie możemy wyłączyć bez ryzyka dużego błędu... ;)
    Pozdrawiam, Light-I
  • #15
    plp
    Level 15  
    Wyłączyć nie można, bo przerwanie realizować miało funkcję ściemniacza, który musi pracować bez względu na wszystko. Można natromiast zmieniać moment komunikacji z DS-em.

    W przerwaniu jest tylko kilka liniejek, ale może po kompilacji to już za dużo na 10 kHz.

    Na razie wiem jeszcze za mało żeby napisać własną obasługę 1wire.

    Dlatego myślę, że przerzucę ściemniacz do pętli głównej, w razie potrzeby dopnę kwarc 16 MHz. Program nie jest zbyt skopmlikowany więc powinien się wyrobić.

    PL
  • #16
    zumek
    Level 39  
    Ja twierdzę , że wszystko o czym pisze "postodawca" jest do zrobienia w Bascomie.Ciekawi mnie też , czy jest potrzebna aż 200 krokowa regulacja pracy silnika(10kHz) skoro i tak nie wykorzystujemy całego okresu przebiegu napięcia zmiennego.Mam pewne wątpliwości czy dobrze przemyślano złożenia programu np. jak wykrywasz przejście napięcia przez "0".Może byś podrzucił kod programu , to sie obada co i jak :wink:.

    Piotrek


    PS
    Nie idź na łatwiznę, bo doświadczenia nigdy dość :)
  • #17
    plp
    Level 15  
    10 kHz, to jest 100 kroków na połówkę fazy. Sterowanie odbywa się w węższym zakresie, więc stopni będzie mniej. Chcę żeby się to regulowało dosyć płynnie, ale może faktycznie można zmniejszyć ilość kroków.

    Przejście przez zero wykrywam przez transoptor podpięty d sieci przez mostek z diod, żeby brać obie połówki, a z drugiej strony do procesora.

    Próbowąłem wcześniej i działało. Tyle że było to zrealizowane normalnie w programie i program nic więcej nie robił.

    Fragment kodu który chciałem wykorzystać mogę wkleić jak będę w domu, czyli popołudniu.

    PL
  • #18
    zumek
    Level 39  
    plp wrote:
    10 kHz, to jest 100 kroków na połówkę fazy. Sterowanie odbywa się w węższym zakresie, więc stopni będzie mniej. Chcę żeby się to regulowało dosyć płynnie, ale może faktycznie można zmniejszyć ilość kroków.

    100 na połówkę czyli 200 na okres :wink:
    plp wrote:

    Przejście przez zero wykrywam przez transoptor podpięty d sieci przez mostek z diod, żeby brać obie połówki, a z drugiej strony do procesora.

    No to aż się prosi , o wykorzystanie przerwań zewnętrznych INT0/INT1 i T0 lub T1, wtedy to nie będziesz wiedział co zrobić z nadmiarem wolnego czasu :wink:

    Piotrek
  • #19
    plp
    Level 15  
    Pisząc o przerwaniach zewnętrznych jak rozumiem miałeś na myśli to, że pojawiający się sygnal z transoptora wywoła przerwanie.
    Też o tym myślałem, tylko że potrzebuję jeszcze odmierzyć dokładnie czas po którym ma zostać wyzwolony triak. Chciałem to zrobić właśnie licząc przerwania. Mógłbym też jak myślę i wcześniej pisałem wykorzystać licznik timer'a.

    Pytanie czy takie przerwanie zewnętrzne też nie wyłoży 1wire ?

    PL
  • #20
    zumek
    Level 39  
    A co powiesz na takie cuś :wink:
    Code:

    $regfile = "m8def.dat"
    $crystal = 8000000
    Dim Tdelay As Word , Do1w As Bit , Tab(9) As Byte
    Const Pulse = 9950       '<10 ms
    Tgate Alias Portb.1       'Pin OC1A
    Config Timer1 = Timer , Prescale = 8
    Stop Timer1
    Config Int0 = Falling
    Config Pinb.1 = Output
    On Int0 Int0_int , Nosave
    Enable Int0
    Enable Interrupts
    Set Tgate
    Tccr1a = &H80       'kiedy licznik T1 zrówna się z Compare1a ,
                      'ustawi niski stan na pinie OC1A=Pinb.1=Tgate

    Tdelay = 4475       '0 < Tdelay < 9950 wow ;) i tak ze 100 kroków zrobiło się 9950,
                        'a z 10kHz pozostało tylko 100Hz

    Do
    Reset Do1w
    While Do1w = 0
    nop
    Wend
    'tu mamy ~9ms dla DS-a ale może nam jeszcze bruździć Timer2
    'więc ja bym do obsługi 1wire zaprzągł przerwanie INT0
    Loop

    'Dobrać elementy transoptora by wyzwolić przerwanie przed zerem sieci ,
    'na czas potrzebny tyrystorowi by się "zatkał"

    Int0_int:       'wykonuje się w 146 taktach
    sbi Portb.1    'wyłączamy bramkę triaka jak najszybciej ;)
    Pushall
    Stop Timer1
    Compare1a = 65536 - Tdelay
    Timer1 = 65536 - Pulse
    Start Timer1
    Set Do1w       'sygnał dla programu głównego  lub obsługa 1wire
    Popall
    Return


    Teoretycznie działa :)

    Piotrek
  • #21
    plp
    Level 15  
    Ciekawy pomysł. Dzisiaj go wypróbuje.

    Na razie mam pytanie, dlaczego użyłeś Nosave i potem Pushall i Popall ? Czy jest różnica gdyby nie użyć Nosave ?

    nop użyłeś dla wizualizacji miejsca ?

    Inny problem - używam M32, a z tego co się doczytałem, to on nie dopuszcza config int0 = falling.

    PL
  • #22
    zumek
    Level 39  
    plp wrote:

    Na razie mam pytanie, dlaczego użyłeś Nosave i potem Pushall i Popall ? Czy jest różnica gdyby nie użyć Nosave ?

    Załadowanie rejestrów na stos , trochę trwa , a ja chcę jak najszybciej wyłączyć zasilanie bramki triaka
    Code:

    ...
    Int0_int:       'wykonuje się w 146 taktach
    sbi Portb,1    'wyłączamy bramkę triaka jak najszybciej ;)
    'sbi nie modyfikuje SREG , więc mogę ją wykonać przed odłożeniem SREG na stos.
    Pushall
    ...

    plp wrote:

    nop użyłeś dla wizualizacji miejsca ?

    Właśnie :wink:
    plp wrote:

    Inny problem - używam M32, a z tego co się doczytałem, to on nie dopuszcza config int0 = falling.

    Coooooo :?:
    To masz chyba Bascoma 1.11.7.4 :?:
    Jak Ci Bascom strajkuje , to zrób to ręcznie:
    Code:

    Mcucr = Mcucr Or 2


    Piotrek
  • #23
    plp
    Level 15  
    Mcucr = Mcucr Or 2

    W helpie wyczytałem że procesory serii Mega mają przerwanie INT0 tylko na niski poziom i wykonują się w kółko jak poziom jest niski. Z drugiej strony ATmega8 Bascom tolerował, ATmega32 już nie.

    Dokumentacja mnie wprowadziła w błąd. Omawiając przerwania jest odesłanie do strony z opcjami uśpienia, a powinno być dużo dalej do zegara systemowego.
    W moim przypadku lepiej będzie Mcucr=Mcucr or 3, ponieważ transoptor zwiera INT0 do masy, a to występuje wtedy gdy w sieci jest napięcie. Mnie interesuje zanik napięcia czyli zbocze narastające na INT0.

    Obsługi DS mam trochę i zajmuje trochę więcej czasu niż 9 ms, ale to nie problem, rozłoży się.
    Jeśli chodzi o obawy z zegarem na 32767 Hz, to do tej pory nie miałem żadnych zakłóceń na 1wire.

    Może zadam głupie pytanie, ale, jak sprawdzić teoretycznie ile czasu będzie wykonywał się jakiś fragment kodu, bez uwzględniania ewentualnych pętli ? Praktycznie sprawdzałem, ale wolałbym teoretycznie.

    Dzięki za wszystkie rady do tej pory.

    PL
  • #24
    plp
    Level 15  
    Trochę mi zeszło z próbami, ale jest tak:

    z przerwaniem dałem sobie radę. Musiałem wyrzucić NOSAVE, PUSHALL i POPALL, bo z tym nie chciało działać. Działa też timer1 i ustawia OC1A na 0. Problem w tym, że potem nie mogę ustawić tej końcówki na 1.

    Testowałem to poniższym kodem i nic. Jak ustawiłem Tccr1a = 64 wtedy końcówka się przełącza, czyli Timer i porównywanie działa. Beeper włącza się i wyłącza więc pętla programu też działa. Nie da się tylko ustawić z powrotem OC1A=1.

    Co zrobić ?

    Pozdrawiam !

    PL

    Dim I As Long
    Dim A As Word
    Dim Tdelay As Word
    Config Pind.5 = Output
    Config Timer1 = Timer , Prescale = 8
    Start Timer1
    Tccr1a = 128
    Compare1a = 55000
    Config Pinb.1 = Output ' to jest beeper

    Do
    If Timer1 > 60000 Then
    Toggle Portb.1
    Set Portd.5
    Timer1 = 0
    End If

    Loop

    End