Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Bascom]Kłopotliwa zmienna (sama sie zeruje)

Miar 15 Paź 2009 18:28 1382 7
  • #1 15 Paź 2009 18:28
    Miar
    Poziom 12  

    program napisany w bascom avr wersja 1.11.6.8 stara dla at90s2313
    problemem są zerujące się zmienne bitowe
    program uruchamiam na płytce testowej avt 3500 tu link do opisu http://www.cyfronika.com.pl/kityavt3/avt3500pdf.pdf
    program nie ma błędów z kompilacją na wyświetlaczach jest 00
    gdy symuluje program zmienne temp i odczyt zerują się cały czas
    a oto program:

    'Sterownik pieca CO

    Code:
    Dim Jednostki As Byte , Dziesiatki As Byte       '  cyfry do wyświetlania temperatury
    
    Dim Temp As Byte         ' temperatura
    Dim Pompka As Bit        ' sterowanie pompką
    Dim Odczyt As Byte
    Dim Cyfrybcd As Byte
    Dim Ktorywysw As Bit
    Enable Interrupts        ' oblokuj przerwania
    Enable Timer0            'odblokuj timer0
    Enable Timer1            'oblokuj timer1
    Config Timer0 = Timer , Prescale = 64       'dziel częstotliwość przez 64
    Config Portb = 255 : Portb = 255       'konfiguracja portu B (cały port jako wyjścia)
    Config Portd = 127 : Portd = &B1111100       'konfiguraja portu D dwa najmłodsze jako wejścia S1 i S2 reszta wyjścia
    On Timer0 Co4ms          'obsługa przerwania dla wyświetlaczy
    On Timer1 Co1s
    Temp = 65
    Do : Loop : End          'pusta pętla

    Co1s:
    Gosub Odczytaj
    If Temp > 50 Then        'start pompki
    Portd.2 = 0              'włącz pompkę     0 to 1 a 1to 0
    End If
    If Temp < 50 Then        'stop pompki
    Portd.2 = 1              'wyłącz pompkę
    End If
    Return

    Co4ms:                   ' tylko obsługa wyświetlaczy
    Toggle Ktorywysw
    Temp = Odczyt
    'If Odczyt > 99 Then      'bo skracamy do 99 dla bcd
    'Odczyt = 99              'skracanie do 99 na wypadek gotowania wody w piecu
    'End If
    Cyfrybcd = Makebcd(odczyt)       'konwersja bcd
    Jednostki = Cyfrybcd And 15
    Dziesiatki = Cyfrybcd
    Shift Dziesiatki , Right , 4       'a tu koniec konwersji bcd
    Select Case Ktorywysw
    Case 0:
    Portd = &B1110111
    Portb = Lookup(jednostki , Tabela)
    Case 1:
    Portd = &B1101111
    Portb = Lookup(dziesiatki , Tabela)
    End Select
    Return

    Odczytaj:
    Portb = 255              'wygasza wyświetlacze
    I2cinit                  'umożliwia pracę szyny
    I2cstart                 'sygnał startu magistrali I2C
    I2cwbyte 145             'wyślij adres "odbiorczy" PCF8591
    I2crbyte Temp , Nack     'z przetwornika do zmiennej Odczyt
    I2cstop                  'sygnał stopu magistrali I2C
    Config Portd = &B1111100 'znów PD.5 i PD.6 są wyjściami
    Return

    Tabela:
    Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144



    Skorygowałem tytuł.
    [zumek]

    0 7
  • Pomocny post
    #2 15 Paź 2009 18:44
    marihires
    Poziom 29  

    A spróbuj tak:

    Code:
    Odczyt=Temp 


    Code:
    Dim Jednostki As Byte , Dziesiatki As Byte       '  cyfry do wyświetlania temperatury
    
    Dim Temp As Byte         ' temperatura
    Dim Pompka As Bit        ' sterowanie pompką
    Dim Odczyt As Byte
    Dim Cyfrybcd As Byte
    Dim Ktorywysw As Bit
    Enable Interrupts        ' oblokuj przerwania
    Enable Timer0            'odblokuj timer0
    Enable Timer1            'oblokuj timer1
    Config Timer0 = Timer , Prescale = 64       'dziel częstotliwość przez 64
    Config Portb = 255 : Portb = 255       'konfiguracja portu B (cały port jako wyjścia)
    Config Portd = 127 : Portd = &B1111100       'konfiguraja portu D dwa najmłodsze jako wejścia S1 i S2 reszta wyjścia
    On Timer0 Co4ms          'obsługa przerwania dla wyświetlaczy
    On Timer1 Co1s
    Temp = 65
    Do : Loop : End          'pusta pętla

    Co1s:
    Gosub Odczytaj
    If Temp > 50 Then        'start pompki
    Portd.2 = 0              'włącz pompkę     0 to 1 a 1to 0
    End If
    If Temp < 50 Then        'stop pompki
    Portd.2 = 1              'wyłącz pompkę
    End If
    Return

    Co4ms:                   ' tylko obsługa wyświetlaczy
    Toggle Ktorywysw
    Temp = Odczyt         'temp otrzymuje wartość Odczyt, której wartość wynosi ...??
                                   'a powinno być tak żeby Odczyt otrzymał wartość Temp.
    'If Odczyt > 99 Then      'bo skracamy do 99 dla bcd
    'Odczyt = 99              'skracanie do 99 na wypadek gotowania wody w piecu
    'End If
    Cyfrybcd = Makebcd(odczyt)       'konwersja bcd
    Jednostki = Cyfrybcd And 15
    Dziesiatki = Cyfrybcd
    Shift Dziesiatki , Right , 4       'a tu koniec konwersji bcd
    Select Case Ktorywysw
    Case 0:
    Portd = &B1110111
    Portb = Lookup(jednostki , Tabela)
    Case 1:
    Portd = &B1101111
    Portb = Lookup(dziesiatki , Tabela)
    End Select
    Return

    Odczytaj:
    Portb = 255              'wygasza wyświetlacze
    I2cinit                  'umożliwia pracę szyny
    I2cstart                 'sygnał startu magistrali I2C
    I2cwbyte 145             'wyślij adres "odbiorczy" PCF8591
    I2crbyte Temp , Nack     'z przetwornika do zmiennej Odczyt  // <--- do zmiennej Temp
    I2cstop                  'sygnał stopu magistrali I2C
    Config Portd = &B1111100 'znów PD.5 i PD.6 są wyjściami
    Return

    Tabela:
    Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144

    0
  • #3 15 Paź 2009 19:15
    Miar
    Poziom 12  

    tak wyświetla 65 (ustalona wartość na początku programu) ale nie czyta z przetwornika analogowo-cyfrowego pcf8591 wartość sie nie zmienia

    0
  • Pomocny post
    #4 15 Paź 2009 19:39
    marihires
    Poziom 29  

    Powiem tak:
    Nie znam się na BASCOMie ale widzę, że END kończy program a dokładnie pustą pętlę w której powinien znajdować się odczyt z przetwornika i wyświetlanie, używając napisanych przez Ciebie funkcji.
    Przykładowo

    siała baba mak.../deklaracja zmiennych

    Do /pętla główna programu wykorzystująca twoje funkcje
    ODCZYT
    WYSWIETL
    Loop
    END

    ODCZYT:
    bla bla bla
    return

    WYSWIETL:
    bla bla bla
    return

    0
  • #5 15 Paź 2009 20:03
    Miar
    Poziom 12  

    Poprawiło się wyświetlacze nie migotają, temperatura się poprawnie wyświetla, jutro poskładam to do kupy i zrobię coś porządnego dodam jeszcze jakieś termostaty i będzie dobrze (chyba). Dzięki:!:

    0
  • #6 15 Paź 2009 22:38
    xury
    Poziom 39  

    Tak był błąd w przypisaniu zmiennych na odwrót.
    Mnie ciekawi tylko gdzie są wartości początkowe timerów ?
    Aco za tym idzie skąd to przekonanie że timer1 wywołuje przerwanie co sekundę ?
    Co do Timera0 też nie jestem pewien czy przerwanie jest co 4ms ?
    A jaka jest częstotliwość taktowania ?
    i gdzie jest dyrektywa $crystal ?
    W dodatku w podprogramie obsługi przerwania masz gosub zupełnie niepotrzebnie. Grozi to rozrastaniem stosu i "malinkami".

    0
  • #8 16 Paź 2009 21:54
    xury
    Poziom 39  

    No dobra pal licho dokładność odmierzania czasu. Tu nie jest aż tak ważna.
    Ale timer1 nie jest skonfigurowany . Pomiar nie ma prawa się odbywać, bo przerwanie od timera1 nie jest wywoływane, a co za tym idzie cała procedura "co1s" ,
    a także ten podprogram "Odczytaj" również nie.
    Nawiasem mówiąc po co on jest ? Nie lepiej zamiast gosub po prostu przenieść zawartość tego podprogramu do obsługi przerwania ?

    i jeszcze jedna sprawa:
    Pompa załacza się jeśli temp jest wieksza niż 50 i włącza się jeśli spadnie poniżej 50
    Podejrzewam, że dalej masz przekaźnik co nią steruje.
    Pomiar (jeśli poprawisz obslugę przerwania) następuje co 1,04 sekundy. W przpadku gdy temperatura spadnie lub wzrośnie o jeden stopień bedziesz miał załaczaniei wyłączanie co chwilę. Może tak zakładałeś, ale ja bym dał albo jakiś przedział temperatur, lub wykorzystując timer1 stworzył kilka zmiennych pomocniczych (jak w zegarze) i sterował pompą w dluższych okresach czasu niż jedna sekunda np. co minutę by dać troche czasu pompce na podziałanie lub odpoczynek. Jednoczesnie można nadal monitorować temperature co sekundę i w razie wystąpienia duzej temperatury włączyć obieg niezależnie.

    0