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

Atmega8+ds18b20+LCD problem z timer0

grzesiug 03 Mar 2009 12:25 2432 9
REKLAMA
  • #1 6229922
    grzesiug
    Poziom 12  
    Zbudowałem układ, który mierzy temp. z trzech ds18b20 i wyświetla na lcd.
    Problem zaczyna się gdy włączę przerwania od timera0 (który tylko w tle odmierza sobie odcinki czasu po 8ms), a mianowicie mierzona temperatura jest nie prawidłowa a później zaczyna się krzaczyć lcd. Ma to być sterownik pieca CO więc potrzebuję odliczać krótkie odcinki czasu na pracę nadmuchu.
    Jak rozwiązać ten problem??

    
    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    
    
    Config Pind.7 = Output                                      'przekaznik elektrozaworu
    Config Pind.6 = Output                                      'przekaznik pompy
    Config Pind.5 = Output                                      'przekaznik wentylatora
    Config Pinb.1 = Input                                       'przycisk "w górę"
    Config Pinb.2 = Input                                       'przycisk "w dół"
    Config Pinb.7 = Input                                       'przycisk "ok"
    Config Pinb.6 = Input                                       'przycisk "menu"
    Config Debounce = 25                                        'czas ponownego sprawdzenia przycisku, eliminacja drgań
    Config 1wire = Portb.0                                      ' konfiguracja portu PB.0 jako wejścia magistrali 1-wire
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
    
    Elektrozawor Alias Portd.7                                  'przypisanie nazw do wyjść i wejść
    Nadmuch Alias Portd.5
    Pompa Alias Portd.6
    
    P_gora Alias Pinb.1
    P_dol Alias Pinb.2
    P_ok Alias Pinb.7
    P_menu Alias Pinb.6
    
    Set P_gora                                                  'włączenie rezystorów podciągających na wejściach
    Set P_dol
    Set P_ok
    Set P_menu
    
    Deflcdchar 0 , 28 , 20 , 28 , 32 , 7 , 4 , 4 , 7            'definicja znaku stopnia z małem znaczkiem celcjusza
    Deflcdchar 1 , 31 , 27 , 21 , 21 , 21 , 21 , 27 , 31        ' "O" na czarnym tle
    Deflcdchar 2 , 31 , 23 , 22 , 21 , 19 , 21 , 22 , 31        ' "K" na czarnym tle
    Deflcdchar 3 , 4 , 14 , 31 , 32 , 32 , 31 , 14 , 4          'strzałeczki
    
    Declare Sub Konfiguracja_czujnikow                          'procedura odczytuje id czujnika
    Declare Sub Odczyt_temperatury(byval Konfig As Byte)
    Declare Sub Dalej
    Declare Sub Dalej1                                          'procedura wysyła id do czujnika
    Declare Sub Dalej2
    
    Dim Id(9)as Byte                                            'zmienna przechowująca id układu ds18b20,9-ty element informuje
                                                                 'o umiejscowieniu czujnika: 1=piec,2=wymiennik ciepła,3=na zewnątrz
    
    Dim I As Byte                                               'zmienna licznikowa
    Dim J As Byte                                               'zmienna licznikowa
    
    Dim Temp_pieca As Single                                    'zmienne przechowujące poszczególne temperatury
    Dim Temp_wymiennika As Single
    Dim Temp_zewnetrzna As Single
    
    Dim Wyjscie As Bit                                          'zmienna do wyjścia z procedur
    
    
    Config Timer0 = Timer , Prescale = 64
    Enable Interrupts
    Enable Timer0
    Load Timer0 , 125
    On Timer0 Odmierz_1s
    Dim Licz_8ms As Byte
    
    
    
    Cls
    
    
    
    
    
    
    Cursor Off
    Do
       
       Debounce P_gora , 0 , Konfiguracja_czujnikow , Sub
    
    Call Odczyt_temperatury(0)
    
    
    
                 Locate 1 , 1
                Lcd "P:" ; Fusing(temp_pieca , "#.#") ; Chr(0) ; " "
    
                Lcd "W:" ; Fusing(temp_wymiennika , "#.#") ; Chr(0) ; " "
    
                Locate 2 , 1
                Lcd "Z:" ; Fusing(temp_zewnetrzna , "#.#") ; Chr(0) ; " "
    
    
    
    
    
    
    
    
    Loop
    End
    
    
    
    
    
    
    
    Sub Konfiguracja_czujnikow                                  'ciało procedury odczytującej id czujników,zapis do eeprom
                                                                'oraz przypisanie umiejscowienia czujników
    
    
                                                                'zawiera ilość układów podłączonych do 1-wire
    Local Ilosc_czujnikow As Byte
    Dim Flaga(2) As Byte
    Local Indeks As Byte
    
    Ilosc_czujnikow = 1wirecount()                              'odczyt ilości czujnikow podłączonych do 1-wire
    
    
    Cls
    
    Id(1) = 1wsearchfirst()                                     'odczyt id pierwszego czujnika
       Id(9) = 1
    
       Lcd "czujnik " ; 1
       Lowerline
       For I = 1 To 9
       Writeeeprom Id(i) , I
    
    
       Lcd Id(i)
       Next I
    
       Wait 1
     Cls
    
    Id(1) = 1wsearchnext()
       Id(9) = 2
    
       Lcd "czujnik " ; 2
       Lowerline
       J = 1
       For I = 10 To 18
       Writeeeprom Id(j) , I
    
    
       Lcd Id(j)
       Incr J
       Next I
    
       Wait 1
     Cls
    
    Id(1) = 1wsearchnext()
       Id(9) = 3
    
       Lcd "czujnik " ; 3
       Lowerline
       J = 1
       For I = 19 To 27
       Writeeeprom Id(j) , I
    
    
       Lcd Id(j)
       Incr J
       Next I
    
       Wait 1
     Cls
    
    Lcd "wykryto: " ; Ilosc_czujnikow ;
    Lowerline
    Lcd " czujnik(i)"
    Locate 2 , 15
    Lcd Chr(1) ; Chr(2)
    
    Bitwait P_ok , Reset
    Waitms 25
    Bitwait P_ok , Set
    Cls
    
    Lcd "zaprog. czujniki"
    Locate 2 , 15
    Lcd Chr(1) ; Chr(2)
    
    Bitwait P_ok , Reset
    Waitms 25
    Bitwait P_ok , Set
    Cls
    Flaga(1) = 0
    Flaga(2) = 1
    
    
    
    
       Do
    
       Call Odczyt_temperatury(1)
       Locate 1 , 1
       Lcd "czujnik1: " ; Fusing(temp_pieca , "#.#") ; Chr(0) ; " "
    
    
       If P_gora = 0 Then
          Waitms 25
    
             If P_gora = 0 Then
                Flaga(2) = Flaga(2) + 1
                   If Flaga(2) = 4 Then
                      Flaga(2) = 1
                   End If
                'Bitwait P_ok , Set
             End If
        End If
    
    
       If P_dol = 0 Then
          Waitms 25
    
             If P_dol = 0 Then
                Flaga(2) = Flaga(2) - 1
                   If Flaga(2) = 0 Then
                      Flaga(2) = 3
                   End If
                'Bitwait P_ok , Set
             End If
        End If
    Indeks = Flaga(2) - 1
    Locate 2 , 1
    Lcd Lookupstr(indeks , Sdata) ; Chr(3)
    Locate 2 , 15
    Lcd Chr(1) ; Chr(2)
    
    
       If P_ok = 0 Then
          Waitms 25
    
             If P_ok = 0 Then
                Wyjscie = 1
                Bitwait P_ok , Set
             End If
    
    
       End If
    
       Loop Until Wyjscie = 1
       Id(9) = Flaga(2)
       Writeeeprom Id(9) , 9
       Flaga(1).flaga(2) = 1
       Wyjscie = 0
    
       Do
    
       Call Odczyt_temperatury(2)
       Locate 1 , 1
       Lcd "czujnik2: " ; Fusing(temp_pieca , "#.#") ; Chr(0) ; " "
    
    
       If P_gora = 0 Then
          Waitms 25
    
             If P_gora = 0 Then
                Flaga(2) = Flaga(2) + 1
                   If Flaga(2) = 4 Then
                      Flaga(2) = 1
                   End If
                'Bitwait P_ok , Set
             End If
        End If
    
    
       If P_dol = 0 Then
          Waitms 25
    
             If P_dol = 0 Then
                Flaga(2) = Flaga(2) - 1
                   If Flaga(2) = 0 Then
                      Flaga(2) = 3
                   End If
                'Bitwait P_ok , Set
             End If
        End If
    
        If Flaga(1).flaga(2) = 1 Then
           Flaga(2) = Flaga(2) + 1
        End If
    
        If Flaga(2) = 4 Then
           Flaga(2) = 1
        End If
    
    Indeks = Flaga(2) - 1
    Locate 2 , 1
    Lcd Lookupstr(indeks , Sdata) ; Chr(3)
    Locate 2 , 15
    Lcd Chr(1) ; Chr(2)
    
    
    
       If P_ok = 0 Then
          Waitms 25
    
             If P_ok = 0 Then
                Wyjscie = 1
                Bitwait P_ok , Set
             End If
    
    
       End If
    
       Loop Until Wyjscie = 1
    
       Id(9) = Flaga(2)
       Writeeeprom Id(9) , 18
       Wyjscie = 0
       Flaga(1).flaga(2) = 1
    
     For Indeks = 1 To 3
       If Flaga(1).indeks = 0 Then
       Flaga(2) = Indeks
       End If
    Next Indeks
    
    Cls
       Do
    
    
       Call Odczyt_temperatury(3)
       Locate 1 , 1
       Lcd "czujnik3: " ; Fusing(temp_pieca , "#.#") ; Chr(0) ; " "
    
       Indeks = Flaga(2) - 1
       Locate 2 , 1
    Lcd Lookupstr(indeks , Sdata)
    Locate 2 , 15
    Lcd Chr(1) ; Chr(2)
    
    
       If P_ok = 0 Then
          Waitms 25
    
             If P_ok = 0 Then
                Wyjscie = 1
                Bitwait P_ok , Set
             End If
       End If
    
       Loop Until Wyjscie = 1
    
       Id(9) = Flaga(2)
       Writeeeprom Id(9) , 27
       Wyjscie = 0
       Cls
    End Sub
    
    
    Sub Odczyt_temperatury(byref Konfig As Byte)                'jeśli parametr =0 odzytuje wszystkie czujniki, jeśli 1 to
                                                                 'pierwszy czujnik jeśli 2 to drugi itd.
    Dim Odczyt(2) As Byte
    Local T As Integer
    Dim Temp As Single
    Local L As Byte
       '1wverify Id(1)
    
       1wreset                                                  'wybranie czujnika poprzez zapis do niego jego nr id
       1wwrite &HCC                                             'start pomiaru przez układ dla wszystkich czyjnikow
       1wwrite &H44
    
       Waitms 750                                               'opóźnienie na czas pomiaru
    
    
       For L = 1 To 3
    
    
                 If Konfig = 1 Then                             'dla potrzeb konfiguracji, odczyt tylko z wybranego czujnika
                  L = 1
                    End If
    
    
                 If Konfig = 2 Then
                  L = 2
                    End If
    
    
                 If Konfig = 3 Then
                  L = 3
                    End If
    
    
    Select Case L
    
       Case 1:
                For I = 1 To 9
                Readeeprom Id(i) , I
                Next I
    
       Case 2:
                J = 1
                For I = 10 To 18
                Readeeprom Id(j) , I
                Incr J
                Next I
    
       Case 3:
                J = 1
                For I = 19 To 27
                Readeeprom Id(j) , I
                Incr J
                Next I
    
       End Select
    
                                                                 'reset magistrali 1-wire
       1wreset
       1wwrite &H55
       1wverify Id(1)                                           'wybranie czujnika poprzez zapis do niego jego nr id
    
       1wwrite &HBE                                             'komenda odczytu układu
    
       Odczyt(1) = 1wread(2)                                    'odczytaj dwa pierwsze bajty
       T = Odczyt(2)                                            'przepisz starszy bajt do zmiennej typu Integer
       Shift T , Left , 8                                       'przesuń ten bajt w lewo na wyższe pozycje
       T = T + Odczyt(1)                                        'przepisz - dodaj młodszy bajt
    
       Temp = T * 0.0625
    
             If Konfig = 0 Then
    
    Select Case Id(9)
       Case 1:
              Temp_pieca = Temp
       Case 2:
              Temp_wymiennika = Temp
       Case 3:
              Temp_zewnetrzna = Temp
    
    
      Case Else:
                 Cls
                 Lcd "Skonfiguruj"
                 Lowerline
                 Lcd "czujniki"
                 Locate 2 , 15
                 Lcd Chr(1) ; Chr(2)
    
                 Bitwait P_ok , Reset
                 Waitms 25
                 Bitwait P_ok , Set
    
                 Gosub Konfiguracja_czujnikow
    
    End Select
            Else
    
              L = 3                                             'gdy parametr różny od zera, dla potrzeb konfiguracji czujnikó
              Temp_pieca = Temp
                                                                'wszystkie odczyty zapisuje pod zmienną Temp_pieca
            End If
    
    
    
          Next L
    
    
    
    End Sub
    
    
    
    
    
    
    
    
    Odmierz_1s:
    
    Load Timer0 , 125
    Incr Licz_8ms
    
    If Licz_8ms = 125 Then
    'Incr Sekundy
    
    Licz_8ms = 0
    
     End If
     Return
    
    
    Sdata:
    Data "PIEC       " , "WYMIENNIK  " , "ZEWNETRZNY "


    Po wyłączeniu przerwań wszystko działa prawidłowo
  • REKLAMA
  • #2 6229973
    Nol
    Poziom 15  
    Bez listingu kodu i schematu nikt się nie domyśli co jest nie tak :) No, chyba że etatowe wróżki zaglądają na forum.
  • REKLAMA
  • #3 6230295
    manekinen
    Poziom 29  
    Na czas komunikacji 1wire musisz wyłączaś przerwania od timer0 (albo go zatrzymywać) bo właśnie to jest przyczyną.
    
    Sub Odczyt_temperatury(byref Konfig As Byte)                'jeśli parametr =0 odzytuje wszystkie czujniki, jeśli 1 to 
                                                                 'pierwszy czujnik jeśli 2 to drugi itd. 
    Dim Odczyt(2) As Byte 
    Local T As Integer 
    Dim Temp As Single 
    Local L As Byte 
       '1wverify Id(1)
     
    disable timer0
    
       1wreset                                                  'wybranie czujnika poprzez zapis do niego jego nr id 
       1wwrite &HCC                                             'start pomiaru przez układ dla wszystkich czyjnikow 
       1wwrite &H44 
    
    enable timer0
    
       Waitms 750                                               'opóźnienie na czas pomiaru 
    
    
       For L = 1 To 3 
    
    
                 If Konfig = 1 Then                             'dla potrzeb konfiguracji, odczyt tylko z wybranego czujnika 
                  L = 1 
                    End If 
    
    
                 If Konfig = 2 Then 
                  L = 2 
                    End If 
    
    
                 If Konfig = 3 Then 
                  L = 3 
                    End If 
    
    
    Select Case L 
    
       Case 1: 
                For I = 1 To 9 
                Readeeprom Id(i) , I 
                Next I 
    
       Case 2: 
                J = 1 
                For I = 10 To 18 
                Readeeprom Id(j) , I 
                Incr J 
                Next I 
    
       Case 3: 
                J = 1 
                For I = 19 To 27 
                Readeeprom Id(j) , I 
                Incr J 
                Next I 
    
       End Select 
    
    
    disable timer0
                                                                 'reset magistrali 1-wire 
       1wreset 
       1wwrite &H55 
       1wverify Id(1)                                           'wybranie czujnika poprzez zapis do niego jego nr id 
    
       1wwrite &HBE                                             'komenda odczytu układu 
    
    enable timer0
    
       Odczyt(1) = 1wread(2)                                    'odczytaj dwa pierwsze bajty
    
  • #4 6232222
    grzesiug
    Poziom 12  
    Niestety nie pomaga, jeśli tylko fragment procedury przechodzi z włączonym przerwaniem już się dzieją cuda,a wszystko wraca do normy gdy wyłączę przerwanie na czas wykonania całej procedury.Ale co mi z takiego timera gdzie większość czasu będzie wyłączony
  • #5 6232897
    dawid512
    Poziom 32  
    A kto powiedział że musisz go wyłączać? Istnieje lepszy sposób: robisz sobie flagę którą resetujesz w pzrerwaniu od timera. Potem wystarczy dodać coś takiego:
    Set Flaga : While Flaga = 1 : Wend  
    Takie coś wstawiasz tam gdzie wcześniej musialeś wyłączać przerwania. Działa to tak że uc czeka aż wykona się przerwanie i dzięki temu wiemy że miało ono miejsce a co za tym idzie mamy jeszce czas do kolejnego.
  • REKLAMA
  • #6 6233365
    psine.pl

    Poziom 30  
    Miałem podobny kłopot którego przyczyną było włączenie optymalizacji kodu wynikowego.

    Sugerowałbym spojrzeć na taka możliwośc jeszcze.

    pozdrawiam
    Marek
  • #7 6235259
    grzesiug
    Poziom 12  
    dziękuję bardzo za zainteresowanie, jednak problemu w żaden sposób rozwiązać nie mogę. Przy zastosowaniu pomysły z pętlą przed przerwaniem i wyłączeniu optymalizacji program zachowuje się stabilnie jednak temperatury nie pokazuje. Dziwi mnie rzecz, że po włączeniu przerwań funkcja 1wirecount() zawsze zwraca 0(mimo zastosowania bezpośrednio przed nią pętli), odczyt id działa poprawnie i nie odczytuje poprawnie temp.
    Muszę przyznać że ręce mi już opadają. Może posiada, ktoś podobny działający program który mógłbym sprawdzić w moim układzie.
    Pozdrawiam

    Przy okazji zapytam jeszcze czy mały brzęczyk piezo mogę podłączyć bezpośrednio do uC czy muszę przez tranzystor( nie chcę mi się lutować bo miejsca na płytce mało)
  • #8 6256340
    tiggerek1982
    Poziom 15  
    witam. dziś także juz nerwa złapałem z tym timer0 i wierzyłem ze na elektrodzie będzie jakieś rozwiązanie, ale z tego co czytam nie tylko ja tak mam;/ .wracając do tematu:

    1.próbowałeś zmienić port dla 1-wire?

    2.jesli problemem jest już zamiana pinów to być może załączenie timer1 pomoże i na nim odliczanie sekundy,przykładowe uruchomienie:
    Config Timer1 = Timer , Prescale = 1024                     'Prescale = 1 | 8 | 64 | 256 | 1024
    
    On Timer1 Label                                             'po przepełnieniu licznik skoczy do etykiety LABEL
    
    Load Timer1 , 15625                                         'załadowanie liczby 100 do TIMER1, po zliczeniu której licznik się przepełni
    
    Enable Timer1                                               'włączamy przerwania licznika
    Enable Interrupts                                           'włączamy globalny system przerwań
    
    Dim J As Byte
    
    
    Cls
    
    'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GŁÓWNY PROGRAM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    Do
    
    Locate 1 , 1
    Lcd "    J = " ; J ; "    "
    
    'Locate 2 , 1
    'Lcd "   TNCT1 = " ; Tcnt1 ; "   "
    
    Loop
    
    End
    
    Label:
    Load Timer1
    Incr J
    Return

    ja wykorzystałem timer1 już w innym celu wiec musze inaczej kombinować. mam nadzieje ze to choć trochę pomoże.

    pozdrawiam
  • REKLAMA
  • #9 6257618
    grzesiug
    Poziom 12  
    pin już próbowałem zmieniać, ale nie pomogło, z timerem1 też próbowałem i również kicha, ale spróbuję jeszcze raz
  • #10 6261375
    rpal
    Poziom 27  
    kolego moge tylko zyczyc uporu i zmyslu analitycznego niestety za ceibie nikt tego nie zrobi a na forum znajdziesz napeno sciezki ktorymi podazac to takze jest pomoc. osobiscie radze zakupic jtag-a zminic procka na taki ktory on obsluguje a analiza bledow bedzie zdecydowanie latwiejsza. brzeczyk bym jednak podlaczyl przez tranzystor bo to zawsze odciaczy koncowke od niepotrzebnych amperow;)
REKLAMA