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

[ATmega8] DS1307, BASCOM AVR - Dziwne zachowanie

Electix 19 Gru 2006 15:50 9714 7
  • #1 19 Gru 2006 15:50
    Electix
    Poziom 20  

    Siemka!

    Od kilku dni spędza mi sen z powiek pewien problem. Mam ATmega8 połączoną z układem DS1307, połączenie na pewno jest poprawne, DS1307 podłączony jest też do bateryjki, a taktowany jest kwarcem zegarkowym. Układ działa poprawnie bo można do niego wpisać dane i da się też je odczytać, po wyłączeniu zasilania RTC pracuje i poprawnie liczy czas. Wszystko byłoby OK gdyby nie fakt iż podczas pracy układ w różnych odstępach czasowych (co 2 do 5 sekund) pokazuje mi jakieś dziwne wartości na wyświetlaczu, np: 131:131.131 131/131/131/131. I nie potrafię zlokalizować przyczyny. Kolejny problem jest taki że pomimo konwersji danych z RTC z kodu BCD na normalny wyświetlane sekundy też jakieś dziwne mi wychodzą z wartościami powyżej 59? Dziwię się bo w tym samym układzie i z podobnymi procedurami układ PCF8583 działał mi dobrze i nie miałem problemów. Natomiast gdy przerobiłem ten układ nieco na potrzeby DS1307 i pozmieniałem procedury, teoretycznie prostszy w obsłudze układ RTC mi nie działa. Na pewno od strony połączeń wszystko jest dobrze, sprawdzałem kilkakrotnie, poza tym jakbym coś źle połączył to miałbym problem z jakąkolwiek komunikacją z RTC. Może przyczyna tkwi w kodzie programu, może procek nie wyrabia? Już sam nie wiem bo program jest prosty a bardziej złożony działał bez zakłóceń na PCF8583, poza tym procesor napędza kwarc 16MHz. Zgłupiałem :(
    Proszę o pomoc, może ktoś miał już taki problem, załączam kod programu:

    Code:

    '***Dyrektywy dla kompilatora***

    $regfile = "m8def.dat"
    $lib "I2C_TWI.LBX"
    $crystal = 16000000

    '***Instrukcje konfiguraji peryferiow***
    '***PORT***
    Config Portd = &B00000011
    Portd = &B11111111
    '***LCD***
    Config Lcdbus = 4
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portb.2 , Rs = Portb.1
    Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
    Deflcdchar 1 , 31 , 4 , 14 , 31 , 4 , 4 , 4 , 31
    Deflcdchar 2 , 31 , 4 , 4 , 4 , 31 , 14 , 4 , 31

    '***TWI***
    Config Scl = Portc.5
    Config Sda = Portc.4
    Config Twi = 100000
    I2cinit

    Config Int0 = Rising
    Config Int1 = Falling
    On Int0 Clk
    On Int1 Key
    Disable Interrupts
    '***Deklaracje zmiennych i procedur***
    Declare Sub Clkrd
    Declare Sub Clkwr
    Declare Sub Clkin
    Declare Sub Clkht
    Declare Sub Keyrd
    Declare Sub Showd
    Declare Sub Mkdec
    Declare Sub Mkbcd



    Dim Clkfl As Byte
    Dim Keyfl As Byte
    Dim Sec As Byte
    Dim Myn As Byte
    Dim Hou As Byte
    Dim Dey As Byte
    Dim Dat As Byte
    Dim Mon As Byte
    Dim Yea As Byte

    Const Rtcw = &HD0                                           'adres zapisu RTC




    Const Rtcr = &HD1                                           'adres odczytu RTC
    Const Rtct = &H00                                           'adres odczytu czasu
    Const Rtcg = &H02                                           'adres rejestru godzin
    Const Rtcd = &H03                                           'adres odczytu daty
    Const Rtcm = &H08                                           'adres początkowy RTC RAM
    Const Rtcc = &H07                                           'adres rejestru kontrolnego RTC
    Const Rtch = &H80                                           'wyłączenie zliczania RTC
    Const Rtcs = &H10                                           'ustawienie rejestru kontrolnego RTC
    Const Rtcz = &H00                                           'ustawienie trybu 24h i RTC start


    Enable Int1
    Enable Interrupts
    Cls
    Lcd "Ustawic Czas?"
    Bitwait Keyfl.7 , Set
    Reset Keyfl.7
    If Keyfl.4 = 1 Then
       Sec = 00
       Myn = 15
       Hou = 15
       Dey = 02
       Dat = 19
       Mon = 12
       Yea = 06
       Clkin
       Mkbcd
       Clkwr
    End If
    Enable Int0
    Do
       Bitwait Clkfl.0 , Set
       Reset Clkfl.0
       Mkdec
       Showd
    Loop
    End

    Sub Mkdec
    Sec = Makedec(sec)
    Myn = Makedec(myn)
    Hou = Makedec(hou)
    Dey = Makedec(dey)
    Dat = Makedec(dat)
    Mon = Makedec(mon)
    Yea = Makedec(yea)
    End Sub

    Sub Mkbcd
    Sec = Makebcd(sec)
    Myn = Makebcd(myn)
    Hou = Makebcd(hou)
    Dey = Makebcd(dey)
    Dat = Makebcd(dat)
    Mon = Makebcd(mon)
    Yea = Makebcd(yea)
    End Sub

    Sub Clkrd
    I2cstart
    I2cwbyte Rtcw
    I2cwbyte Rtct
    I2cstart
    I2cwbyte Rtcr
    I2crbyte Sec , Ack
    I2crbyte Myn , Ack
    I2crbyte Hou , Ack
    I2crbyte Dey , Ack
    I2crbyte Dat , Ack
    I2crbyte Mon , Ack
    I2crbyte Yea , Nack
    I2cstop
    End Sub

    Sub Clkwr
    I2cstart
    I2cwbyte Rtcw
    I2cwbyte Rtct
    I2cwbyte Sec
    I2cwbyte Myn
    I2cwbyte Hou
    I2cwbyte Dey
    I2cwbyte Dat
    I2cwbyte Mon
    I2cwbyte Yea
    I2cstop
    End Sub

    Sub Clkin
    I2cstart
    I2cwbyte Rtcw
    I2cwbyte Rtcc
    I2cwbyte Rtcs
    I2cstop
    I2cstart
    I2cwbyte Rtcw
    I2cwbyte Rtcg
    I2cwbyte Rtcz
    I2cstop
    End Sub

    Sub Clkht
    I2cstart
    I2cwbyte Rtcw
    I2cwbyte Rtct
    I2cwbyte Rtch
    I2cstop
    End Sub

    Sub Showd
    Cls
    Cursor Off
    Lcd Hou ; ":" ; Myn ; "." ; Sec
    Lowerline
    Lcd Dey ; "/" ; Dat ; "/" ; Mon ; "/" ; Yea
    End Sub


    Sub Keyrd
    Set Keyfl.7
    If Pind.4 = 0 Then
       Keyfl.0 = 1
    Elseif Pind.5 = 0 Then
       Keyfl.1 = 1
    Elseif Pind.6 = 0 Then
       Keyfl.2 = 1
    Elseif Pind.7 = 0 Then
       Keyfl.3 = 1
    Elseif Pinb.0 = 0 Then
       Keyfl.4 = 1
    End If
    End Sub

    Clk:
    Set Clkfl.0
    Clkrd
    Return

    Key:
    Keyrd
    Return


    Z góry wielkie dzięki i POZDRAWIAM!!

    0 7
  • CControls
  • #2 19 Gru 2006 16:41
    robgold
    Poziom 14  

    Strasznie to masz skomplikowane, po co definujesz wszystkie adresy skoro DS ma autoinkrementacje ?
    Jesli czytasz podajesz od razu 0 jako rejestr. Nie musisz wtedy wógole deklarowac stalych.

    Moja procedurka w 100% dzialajaca:

    Code:

    Sub Odczytdataiczas
    I2cstart
    I2cwbyte 208
    I2cwbyte 0
    I2cstart
    I2cwbyte 209
    I2crbyte Sekundy , Ack
    I2crbyte Minuty , Ack
    I2crbyte Godziny , Ack
    I2crbyte Dzientygodnia , Ack
    I2crbyte Dzien , Ack
    I2crbyte Miesiac , Ack
    I2crbyte Rok , Nack
    I2cstop
    Sekundy = Makedec(sekundy)
    Minuty = Makedec(minuty)
    Godziny = Makedec(godziny)
    Dzientygodnia = Makedec(dzientygodnia)
    Dzien = Makedec(dzien)
    Miesiac = Makedec(miesiac)
    Rok = Makedec(rok)
    End Sub


    Zapis
    Code:

     Godziny = Makebcd(godziny)
       Minuty = Makebcd(minuty)
       Dzientygodnia = Makebcd(dzientygodnia)
       Dzien = Makebcd(dzien)
       Miesiac = Makebcd(miesiac)
       Rok = Makebcd(rok)

       '----- Zapis do DS1307 RTC -----
       I2cstart
       I2cwbyte 208
       I2cwbyte 0
       I2cwbyte 0
       I2cwbyte Minuty
       I2cwbyte Godziny
       I2cwbyte Dzientygodnia
       I2cwbyte Dzien
       I2cwbyte Miesiac
       I2cwbyte Rok
       I2cstop

    0
  • CControls
  • Pomocny post
    #3 19 Gru 2006 17:05
    Skubik
    Poziom 15  

    A masz kondensator przy nóżkach zasilających DS1307? czasem bez kondensatora układ wariuje

    0
  • #4 19 Gru 2006 18:38
    Electix
    Poziom 20  

    Hej! :)

    No już jest zdecydowanie lepiej, chodziło o ten kondensator przy zasilaniu, rzeczywiście bez niego układ wariuje.
    Wielkie dzięki dla Skubika!!!!
    Mam jeszcze problem z tymi sekundami. One nadal przybierają dziwne wartości pomimo iż konwertuję je z kodu BCD.

    0
  • #5 19 Gru 2006 19:16
    Andy74
    Poziom 24  

    Witam.
    Niech zgadnę - na końcu sekund wyświetla się zawsze "9" przy nieprawidłowej wartości?

    Jeśli tak, to zmień

    Code:
    Lcd Hou ; ":" ; Myn ; "." ; Sec

    na
    Code:
    Lcd Hou ; ":" ; Myn ; "." ; Sec ; "   "

    i sprawdź czy będzie poprawa :)

    A najlepiej zapisz sobie
    Code:
    Lcd Bcd(Hou) ; ":" ; Bcd(Myn) ; "." ; Bcd(Sec)
    
    Lowerline
    Lcd Bcd(Dey) ; "/" ; Bcd(Dat) ; "/" ; Bcd(Mon) ; "/" ; Bcd(Yea)

    i wyrzuć podprogram konwersji na DEC (Sub Mkdec...End Sub).

    Pozdrawiam
    Andy

    0
  • #6 19 Gru 2006 19:48
    Electix
    Poziom 20  

    Hejka!

    Pomogło bo sekundy idą jak trzeba, natomiast reszta się totalnie wysypała i znów układ czasami wariuje jak pisałem na początku. Dziwne i to bardzo i zastanawia mnie fakt czemu z PCF8583 wcześniej nie miałem takich problemów. Będę musiał jednak szybciej przerzucić się na ASM i C bo ten cały BASCOM mimo szczerych chęci autora to wielkie G****. :(
    Sprawdzę jeszcze połączenia, bo to plątanina kabelków na płytce uniwersalnej, choć wątpię bo gdy założę drugi procek z innym programem obsługujący 1-wire działa stabilnie, co świadczy o sprawności sprzętu.
    Tematu jeszcze nie zamykam bo mam nadzieję że wspólnymi siłami rozwiążemy ten problem by inni nie musieli sie tak wkurzać jak ja...

    Pozdrawiam :)

    0
  • #7 20 Gru 2006 00:02
    Skubik
    Poziom 15  

    Mam jeszcze jedną myśl. Kwarc musi byc jak najblizen układu DS1307 najlepiej przylutowac bezposrednio do nózek układu

    0
  • #8 20 Gru 2006 00:34
    Electix
    Poziom 20  

    Hej!

    I jest tak jak mówisz - Skubik. :P Kwarc jest przy samym układzie, przylutowany bezpośrednio. Takich strategicznych rzeczy staram się nie łączyć kabelkami...:) Myślałem że coś nie tak może być z ATmega8, że może się zawiesza, może resetuje, może jakieś zakłócenia pracy kwarcu mikrokontrolera ( pracuje na 16MHz)? Ale włączyłem w fuse bits CKOPT co nic nie zmieniło i sprawdziłem czy coś się nie wiesza, ale program idzie. Wydaje mi się że to kwestia algorytmu i działania programu. Chyba to za wolno chodzi i dlatego tak jest. Już kiedyś miałem podobny problem z DS18B20 i obsługą tego w przerwaniach i dopiero jak wpuściłem program w pętlę główną i zaczął działać. Teraz chyba też tak spróbuję, jak się okaże że to jest przyczyną, od ręki odstawiam BASCOM, :( bo co próbuję uruchomić jakiś bardziej złożony algorytm lub wykorzystać przerwania to wszystko się sypie pomimo teoretycznej poprawności. Koniec marudzenia idę spać... :)

    Jakby ktoś miał jeszcze jakieś sugestie, pomysły to chętnie wysłucham! :)

    Cześć!!


    Czyżby nikt nie miał już żadnych pomysłów? :cry:

    0