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

[bascom]Timer zamiast waitms do obslugi dgran przyciskow i 1wire

gomes 13 Sty 2012 14:30 2987 11
  • #1 10390775
    gomes
    Poziom 15  
    Witam,
    Napisalem wieksza czesc kodu lecz po drodze napotkalem na przeszkode w postaci waita przy odczytywaniu temeratury. Chcialbym calkowicie zrezygnowac z waitow, bitwaitow itp wiec mysle nad wykorzystaniem timera.
    Napisalem maly programik testujacy lecz nie do konca dziala prawidlowo

    
    $regfile = "m8def.dat"
    $crystal = 8000000
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Timer0 = Timer , Prescale = 64                       '8MHz/64/250/500 = 1 sekunda
    Config 1wire = Portd.0
    On Timer0 Przerwanie
    Enable Interrupts
    Enable Timer0
    Dim Licznik As Integer
    Dim Pom As Byte
    Dim I As Integer                                            'zmienne do odczytu temp.
    Dim S As Single
    Dim T As String * 4
    Deflcdchar 0 , 6 , 9 , 6 , 32 , 32 , 32 , 32 , 32           ' znak stopnia
    Declare Sub Pomiar
    Timer0 = 6
    Licznik = 0                                                 'flaga do zliczania 252us
    Pom = 0                                                     'flaga pomocnicza do okreslenia czy uplynelo 252us
    
    
    
    Do
    Call Pomiar()
    Pom = 0
    Loop
    End
    
    Sub Pomiar()
    
     1wreset
     1wwrite &HCC
     1wwrite &H44
     'Waitms 250 'to chce zastapic timerem
     Start Timer0
     If Pom = 1 Then
       1wreset
       1wwrite &HCC
       1wwrite &HBE
       I = 1wread(2)
       S = I / 16
       T = Fusing(s , "##.#")
       Stop Timer0
     End If
    
     'If Menu = 2 Then
     Locate 1 , 3
     Lcd "Temp:" ; T ; Chr(0) ; "C  "
     Lowerline
     Lcd "                "
     'End If
     'If Menu = 3 Then
     'Locate 2 , 1
     'Lcd "Temp:" ; T ; Chr(0) ; "C  "
     'End If
     End Sub
    
    Przerwanie:
    Counter0 = Counter0 + 6                                     '256-6=250
    Incr Licznik
    'If Licznik = 500 Then                                       'jeśli zmienna licznik równa się 500 (czyli
                                                              'odliczone zostało 500*2ms=1sek), to
    'Toggle Portb.0
    'Licznik = 0
    'End If
    If Licznik = 126 Then 'odliczanie 252ms
    Pom = 1
    Licznik = 0
    End If
    
    Return
    

    Problem w tym, ze nie wiem gdzie zerowac zmienna pomonicza 'pom'. oraz kawalek
    1wreset
     1wwrite &HCC
     1wwrite &H44

    jest wykonywany w kazdej petli a powinien raz przy pelnym odczycie.
    Czy ide w dobrym kierunku ? Jak mozna to przerobic ?
    Szukalem, lecz nie moglem znalesc innego kodu w ktorym jasno by bylo wyjasnione jak zastapic timerem waity (bede potrzebowal tego rownierz do obslugi drgania stykow).

    Pozdrawiam
  • #2 10390940
    FastProject
    Poziom 28  
    Po pierwsze to pisujesz to timera wartość 250, czyli przerwanie przychodzi ci nie co 2ms a co 48us.
  • #3 10391562
    gomes
    Poziom 15  
    hm
    Zegar = 8MHz
    Preskaler = 64
    Obliczenia: 1 / (8MHz / 64) [us]
    timer "cyknie" co 8mikrosekund, przepelnienie co 250x8us=2ms
    2ms*126=252ms
    Co zle licze?

    
    $regfile = "m8def.dat"
    $crystal = 8000000
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Timer0 = Timer , Prescale = 64                       '8MHz/64/250/500 = 1 sekunda
    Config 1wire = Portd.0
    On Timer0 Przerwanie
    Enable Interrupts
    Enable Timer0
    Dim Licznik As Integer
    Dim Pom2 As Byte
    Dim Pom1 As Byte
    Dim I As Integer                                            'zmienne do odczytu temp.
    Dim S As Single
    Dim T As String * 4
    Deflcdchar 0 , 6 , 9 , 6 , 32 , 32 , 32 , 32 , 32           ' znak stopnia
    Declare Sub Pomiar
    Timer0 = 6
    Licznik = 0
    Set Portd.4
    Config Portd.4 = Output
    Pom1 = 0
    Pom2 = 0
    
    
    Do
    Call Pomiar()
    Loop
    End
    
    
    Sub Pomiar()
    If Pom1 = 0 Then                                            'raz wchodzi i czeka na pelny odczyt
     1wreset
     1wwrite &HCC
     1wwrite &H44
     
     'Waitms 250 'to chce zastapic timerem
     Start Timer0 
     End If
       If Pom2 = 1 Then                                         'po odczekaniu 252ms odczytuje i wyswietla wynik
       Stop Timer0
       1wreset
       1wwrite &HCC
       1wwrite &HBE
       I = 1wread(2)
       S = I / 16
       T = Fusing(s , "##.#")
       Locate 1 , 3
       Lcd "Temp:" ; T ; Chr(0) ; "C  "
       Lowerline
       Lcd "                "
       Pom1 = 0                                                 'po restarcie znowu mozna zainicjowac polaczenie 1wire
       Pom2 = 0                                                 'po odczekaniu ponownie mozna odczytac i wyswietlic temp
       End If
    End Sub
    
    Przerwanie:
    Pom1 = 1
    Counter0 = Counter0 + 6                                     '256-6=250
    Incr Licznik
       'If Licznik = 500 Then                                       'jeśli zmienna licznik równa się 500 (czyli
                                                              'odliczone zostało 500*2ms=1sek), to
       'Toggle Portd4.0
       'Licznik = 0
       'End If
    If Licznik = 126 Then
       Pom2 = 1
       Licznik = 0
       'Toggle Portd.4
    End If
    
    Return
    

    Czy tak powinno odbywac sie zastepowanie waitow timerem ?
  • #4 10392110
    Konto nie istnieje
    Poziom 1  
  • #5 10393103
    gomes
    Poziom 15  
    Docelowy uklad bedzie sporo robil > 2 czujniki temp, odczyt godziny z pcf8583 i alarmu, wszystko sterowane pilotem(jak bedzie trzeba to na przerwaniu), jak sie uda to komunikacja z pc przez uart, sterowanie 7 przekaznikami, regulacja rgb przez pwm, obsluga przyciskow bez debounce i waitow, obsluga menu ...

    Jak pisalem wczesniej powyzszy program to tylko wersja testowa do timerow. W obecnej wersji testowej mysle, ze dziala to tak:
    Poczatkowo flagii sa zerowane, w glownej petli wywolywany jest sub(docelowo jest menu z selectem), flaga pom1 jest po to, zeby w czasie oczekiwania na przerwanie nie byla ponownie wykonywania inicjalizacja, uruchamiany jest timer0 w ktorym pom1 jest zwiekszana do momentu obslugi pelnego odczytu, jak nastapi przerwanie to pom2 'wpuszcza' do if'a gdzie timer jest zatrzymywany aby umozliwic odczyt, konwersje i wyswietlanie aktualnej temp. Nastepnie pom1 jest zerowana co umozliwia rozpoczecie procesu od poczatku (dlatego timer0 jest ponownie wlaczany przy kolejnej inicjalizacji odczytu).

    Jest to moj pierwszy wiekszy projekt stad prosze o pomoc na forum. Do tej pory udalo mi sie uruchomic wszystko w oddzielnych programach, teraz staram sie polaczyc to w 1 duzy. Jak zabraknie miejsca w procko mozliwa bedzie migracja do atmegi32.

    Sam program przedstawiony powyzej dziala ale przy probie dolaczenia go np do odczytu czasu z rtc(jak jest odczyt rtc to wylaczam przerwania, po odczycie wlaczam ponownie) to wystepuje problem.

    Zastanawiam sie czy jeden timer moglby jednoczesnie obslugiwac waity w 1wire oraz debounce przy przyciskach(wujek google nie chcial mi pokazac podobnego przykladu).
  • #6 10393400
    mirekk36
    Poziom 42  
    gomes napisał:

    Zastanawiam sie czy jeden timer moglby jednoczesnie obslugiwac waity w 1wire oraz debounce przy przyciskach(wujek google nie chcial mi pokazac podobnego przykladu).


    Ja wprawdzie już w Bascomie dawno nie programuję, ale na pewno da radę wszystko zrobić o czym piszesz, czyli połączyć wiele różnych funkcjonalności łącznie z obsługą 1wire. Poniżej masz przykład jak to może działać i to bez żadnych problemów. Tu wprawdzie już kod pisany był w C ale kiedyś robiłem takie rzeczy również w Bascomie, choć było ciaśniej i mniej wygodnie. Nie mniej jednak da radę, zobacz:

    http://mirekk36.blogspot.com/2011/09/fakty-i-mity-nt-rzekomych-problemow-z.html
  • #7 10393550
    gomes
    Poziom 15  
    Pana ksiazke posiadam lecz w c nie moglem poradzic sobie z rc5 i lcd dlatego wrocilem do bascoma gdzie wszystko podane jest na tacy(znacznie przystepnie lecz zdaje sobie sprawe, ze mniej wydajnie). Chce nabrac troche obycia z uc oraz dobrych nawykow(stad proba ucieczki od waitow) a za jakis czas pewnie wroce do c.

    Wracajac do tematu czy moglbym prosic przynajmniej o pseudo kod obslugi przykladowo drgania w przyciskach , wysterowania przekaznika np przez 2s oraz komunikacji 1wire jednym timerem (atmega8 ma az 2 timery wiec pewnie szybko skoncza sie jego mozliwosci chcac napisac kod bez zatrzymywania)
  • #8 10393598
    janbernat
    Poziom 38  
    No samo posiadanie książki to trochę mało- moze jednak przeczytać.
    Ale po przeczytaniu książki Mirka zwykle już się nie wraca do Bascoma.
    To wszystko zaczyna się mocno rozjaśniać po przeczytaniu rozdziału- "wstęp do systemów czasu rzeczywistego".
    Wartość dydaktyczna tej książki w 90% zawiera się w tym krótkim rozdziale.
    Resztę- to można sobie od biedy znaleźć w sieci i robić poszczególne zadania- no i nie mogąc ich sensownie połączyć.
    W zasadzie Mirek oprócz swojej funkcji "super debounce" mógłby zamieścić w następnym wydaniu jakąś funkcję "very simple debounce".
    No ale to tylko takie chciejstwo- ostatecznie tę pierwszą można mocno okroić.
    Ale ze strony dydaktyki- było by to pożyteczne.
  • #9 10393773
    mirekk36
    Poziom 42  
    gomes napisał:
    Pana ksiazke posiadam lecz w c nie moglem poradzic sobie z rc5 i lcd dlatego wrocilem do bascoma gdzie wszystko podane jest na tacy(znacznie przystepnie lecz zdaje sobie sprawe, ze mniej wydajnie). Chce nabrac troche obycia z uc oraz dobrych nawykow(stad proba ucieczki od waitow) a za jakis czas pewnie wroce do c.


    Szkoda, że się kolega tak łatwo poddał - a przecież ja nie dostałem ani jednego maila że coś jest niezrozumiałe, żebym w czymś pomógł itp (od kolegi) ... a do mnie można się śmiało zwrócić - i wystarczy raz zaskoczyć a potem już samo leci. ... tylko fakt, trzeba co najmniej raz przeczytać książkę wcześniej tak od deski do deski - do poduszki.
  • Pomocny post
    #10 10394034
    Mundi1970
    Poziom 24  
    gomes napisał:
    Wracajac do tematu czy moglbym prosic przynajmniej o pseudo kod obslugi przykladowo drgania w przyciskach , wysterowania przekaznika np przez 2s oraz komunikacji 1wire jednym timerem (atmega8 ma az 2 timery wiec pewnie szybko skoncza sie jego mozliwosci chcac napisac kod bez zatrzymywania)


    Cały dowcip polega na tym że z tego 8 bitowego timera możesz sobie zrobić więcej "liczników-timerów" 8, 16, 32 bitowe ;). Mały przykład:

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #11 10398453
    gomes
    Poziom 15  
    Dzieki za odp. Zaraz bede walczyl z timerami. Wlasnie koncze czytac 8.4 rodzial ksiazki Pana Kardasia i zrodzil sie pomysl sprawdzenia czy bascom ma cos takiego jak wskazniki, tworzenie zmiennych na stosie w funkcjach, przekazywanie ich...

    Na szybko stworzylem cos takiego
    
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    
    Dim Pom1 As Integer
     Dim Pom2 As Integer
    Declare Function Cos1(pom1 As Integer) As Integer
    Declare Sub Cos2
     Pom1 = 0
    Pom2 = 0
     Do
     Pom1 = Cos1(pom1)
    'Gosub Cos2
    Locate 1 , 1
    Lcd Pom1
    Locate 2 , 1
    Lcd Pom2
    
    Wait 1
    Loop
    End
    
    Function Cos1(pom1)
    Incr Pom1
    Incr Pom2
    End Function
    
    'Sub Cos2
    'Incr Pom2
    'End Sub
    

    i ku memu zdziwieniu, na lcd wartosci pom1 i pom2 wzrastaja 'rownomiernie'(a w wedlug mnie tylko pom1 powinna pokazywac sie zwiekszana) nie wazne czy wywoluje gosub'em, call'em czy zwiekszam bezposrednio w ciele funkcji. Help wpomina o przekazywaniu parametrow przez adres wiec dlaczego Pom2 tez sie zwieksza ?
  • #12 10400496
    Mundi1970
    Poziom 24  
    gomes napisał:
    i ku memu zdziwieniu, na lcd wartosci pom1 i pom2 wzrastaja 'rownomiernie'(a w wedlug mnie tylko pom1 powinna pokazywac sie zwiekszana) nie wazne czy wywoluje gosub'em, call'em czy zwiekszam bezposrednio w ciele funkcji. Help wpomina o przekazywaniu parametrow przez adres wiec dlaczego Pom2 tez sie zwieksza ?


    No raczej niema w tym nic dziwnego, Pom1 i Pom2 są zmiennymi globalnymi. Przykład funkcji zwracającej wynik, dana przekazywana jest jako wartość. Można uruchomić w symulatorze. Jeżeli dana do funkcji będzie przekazana przez referencje, to po wykonaniu funkcji zmienna Pom1 i Wynik będą równe.

    Kod: text
    Zaloguj się, aby zobaczyć kod
REKLAMA