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

[ATmega16][Bascom AVR] problem z ds18b20

pedro_b 24 Maj 2008 00:08 5553 14
REKLAMA
  • #1 5174220
    pedro_b
    Poziom 10  
    Nie umiem odczytać temperatur z ds18b20. Rezystor podciągający jest(4.7k), VDD i GND też są podłączone. Linia danych podpięta jest pod pb.7

    Aha wyświetliłem sobie też wartości odczytanych bajtów, zarówno 1szy jaki drugi mają wartość 0xFF.

    podaję kod może koś znajdzie błąd.
    
    
    Dim Cyfra(10) As Byte
    Cyfra(1) = &B00000101
    Cyfra(2) = &B11011101
    Cyfra(3) = &B01000110
    Cyfra(4) = &B01010100
    Cyfra(5) = &B10011100
    Cyfra(6) = &B00110100
    Cyfra(7) = &B00100100
    Cyfra(8) = &B01011101
    Cyfra(9) = &B00000100
    Cyfra(10) = &B00010100
    
    
    Ddrc = &HFF;
    Ddra = &HFF;
    
    
    
    
    
           'Timer0 będzie odmierzał dokładnie 1 sekundę 8MHz/64/250/500 = 1 sekunda
    $crystal = 80000000                                         'częstotliwo.ć taktowania mikrokontrolera
    
    Config Timer0 = Timer , Prescale = 64                       'deklaracja timera jako czasomierza 'z prescalerem 64
    Config 1wire = Portb.7                                      'konfiguracja magistrali 1wire
    
    
    
    On Timer0 Przerwanie_co_2ms                                 'deklaracja jaka etykieta obsługuje 'przepełnienie od timer0
    On Int0 Przerwanie
    
    
    Dim Licznikled As Integer                                   'zmienne licznikowa
    Dim Licz As Integer
    Dim Iiii As Integer
    Dim T As Integer
    
    Dim Pom As Integer
    Dim B1 As Single,
    
    
    Enable Interrupts                                           'odblokowanie globalnych przerwań
    Enable Timer0                                               'odblokowanie przerwania od przepełnienia timer0
    Timer0 = 6                                                  'wpisanie warto.ci początkowej 6 do timera,
                                                                'czyli timer będzie zliczał 250 (256-6) impulsów
    Licznikled = 0                                              'wyzerowanie zmiennej licznikowej
    Enable Interrupts                                           ' zezwolenie na obsługę przerwań
    Enable Int0
    
    
    
    
    Enable Interrupts
    Enable Timer0
    
    
    
    
    Do
       Disable Interrupts
    
       1wreset
       1wwrite &HCC                                             'komenda skip ROM
       1wwrite &H44                                             'komenda convert T
       Enable Interrupts
       Waitms 750
       Disable Interrupts
       1wreset
       1wwrite &HCC                                             'komenda skip ROM
       1wwrite &HBE                                             'komenda read
    
       B1 = 1wread(2)                                           'odczyt z termometru
       T = B1
       T = T * 10
       T = T \ 16
       T = T \ 10
       Iiii = T
    
       Enable Interrupts
       Waitms 250
       Waitms 250
       Waitms 250
       Waitms 50
       Disable Interrupts
    Loop
    End                                                         'koniec programu
    
    
    Przerwanie_co_2ms:                                          'podprogram przerwania od przepełnienia timer0 wywolywanego co 2 ms
       Counter0 = Counter0 + 6                                  'ustawienie początkowej warto.ci timera0 poprzez
       'dodanie do niego warto.ci 6 (odliczone zostanie
       'dokładnie kolejne 250 impulsów)
       Incr Licznikled                                          'zwiększenie licznika
       Incr Licz
    
    
       If Licznikled = 1 Then
          Porta = &B11111110                                    'najbardziej znacząca cyfra
          Pom = Iiii Mod 1000
          Pom = Pom / 100
          Portc = Cyfra(pom + 1);
       End If
    
       If Licznikled = 3 Then
          Porta = &B11111101
          Pom = Iiii Mod 100
          Pom = Pom / 10
          Portc = Cyfra(pom + 1);
       End If
    
       If Licznikled = 5 Then
          Porta = &B11111011
          Pom = Iiii Mod 10
          Portc = Cyfra(pom + 1);
       End If
    
       If Licznikled = 7 Then
          Licznikled = 0                                        'wyzeruj zmienną licznikled
       End If
    
    
    Return                                                      'powrót z przerwania
    
    
    Przerwanie:
         ' Incr Iiii
    Return
    
    
  • REKLAMA
  • REKLAMA
  • #3 5174292
    pedro_b
    Poziom 10  
    usunąłem jedno zero dalej lipa
  • REKLAMA
  • #4 5174305
    don diego
    Poziom 32  
    Niestety na tym się kończy moja znajomość Bascoma:) Masz dobrze ustawione fuse bity?
  • #5 5174314
    pedro_b
    Poziom 10  
    chyba tak
    wyłączyłem tylko JTAGA i zmieniłem zegar na 8mhz
  • #6 5177158
    dawid512
    Poziom 32  
    Utrudniasz sobie zycie niesamowicie tym twoim programem. Niepotrzebnie pakujesz się w przerwania. Tutaj masz chyba najprostsza wersje kodu:
    $regfile = "m32def.dat"
    $crystal = 16000000
    
    
    Config Lcdbus = 4
    Config Lcd = 24 * 2
    Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
    Config 1wire = Porta.2                                      ' termometr ds18b20
    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
    
    Cursor Off
    Cls
                                                       'pomiar temp. na termometrze ds18b20
    Do
    
       1wreset
       1wwrite &HCC
       1wwrite &H44
       Waitms 750
    
       1wreset
       1wwrite &HCC
       1wwrite &HBE
    
       I = 1wread(2)
       S = I / 16
       T = Fusing(s , "##.#")
    
       Locate 1 , 1
       Lcd "Temp:" ; T ; Chr(0) ; "C"
    
    Loop 
    
  • #7 5178744
    pedro_b
    Poziom 10  
    Zrobiłem wg twojego programu, i wyłączam przerwania na czas odczytu temperatury. Termometr cały czas zwraca 0.

    Czy problem może tkwić w tym że korzystam z wewnętrznego kwarcu?
  • REKLAMA
  • #8 5178811
    dawid512
    Poziom 32  
    Jeżeli korzystasz z wew. zegara 8MHz i w programie masz tez 8MHz to powinno dzialac. Powiedz mi tylko po co wylaczasz przerwania? W moim programie z nich nie korzystasz wiec po co je wylaczasz?
  • #9 5178997
    pedro_b
    Poziom 10  
    bo za pomocą przerwań odsługuję wyświetlacz 8 seg.
  • #10 5180196
    dawid512
    Poziom 32  
    Zamiast wyłączać przerwania możesz zastosować pewien trik. Mianowicie zadeklaruj sobie jakas flage. Gdy konczy sie przerwanie zresetuj ja. Wtedy bedziesz wiedzial ze sie zakonczylo i ze masz troche czasu do nastepnego. Potem piszesz cos takiego :

    Set Flaga : While Flaga = 1 : Wend


    To umieszczaj w miejscu gdzie masz odczyt temp. Pamietaj o tym aby umiescic to tyle razy ile tzreba i zeby program zdazyl sie wykonac zanim nastapi przerwanie.
  • #11 5182554
    pedro_b
    Poziom 10  
    chyba problem tkwi w czym innym.
    procedura reset zwraca mi kod błędu ERR = 1.

    Myślałem że pomyliłem VDD z GND, gdy zamienię ja miejscami dalej to samo.
  • #12 5183148
    don diego
    Poziom 32  
    pedro_b napisał:
    Myślałem że pomyliłem VDD z GND, gdy zamienię ja miejscami dalej to samo.

    Zamiana miejscami raczej nie jest dobrym pomysłem. Możesz spróbować pracy w trybie parasite. U mnie działa tak czujnik po odwrotnym podłączeniu zasilania.
  • #13 5183446
    dawid512
    Poziom 32  
    Ku woli ścisłości DS-a podlaczasz tak:
    1 noga to masa
    2 noga to linia danych ktora podpnasz do procka i na ktorą przez rezystor 4.7kΩ podajesz napiecie 5V
    3 noga to zasilanie 5V.
  • #15 5187020
    pedro_b
    Poziom 10  
    czujka już działa. Rozwiązałem to w ten sposób:
    
    Do
     Disable Int0
     Disable Timer0
    
       Dsid1(1) = 1wsearchfirst()
    
       1wreset                                                  'inicjacja magistrali 1WIRE
       While Err = 1
         1wreset
       Wend
    
       1wwrite &H55
       1wverify Dsid1(1)
       1wwrite &HBE
       B1 = 1wread()
       B2 = 1wread()
       T = Makeint(b1 , B2)
       T = T * 10
       T = T / 16
       If T <> 0 Then
          Show = T
       End If
       1wreset
       While Err = 1
         1wreset
       Wend
       1wwrite &HCC
       1wwrite &H44
    
     Enable Int0
     Enable Timer0
     Waitms 2750
    Loop
    End
    



    Dziękuję wszystkim chętnym za pomoc. :D
REKLAMA