Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[atmega8][bascom][pcf8583]program nie działa

pier 29 Oct 2009 12:24 2737 3
  • #1
    pier
    Level 23  
    Witam.
    Żeby się nie rozpisywać, mam taki kod do zegara:
    Code:

                                 '----Zegar nixie LC-531----.'

    'opis złącza ISP
    'czerwony - "+"
    'zielony - RESET
    'biały - MISO
    'niebieski - SCK
    'brązowy - MOSI
    'czarny  - "-"


    '------opis podłączenia lamp----.'

    'segmenty-sterowanie 74141:

    'A-pb.0
    'B-pb.1
    'C-pb.2
    'D-pb.3

    'pozycje:

    'godziny dziesiatki-pc.0
    'godziny jednosci-pc.1
    'minuty dziesiatki-pc.2
    'minuty jednosci-pc.3
    'sekundy dziesiatki-pc.4
    'sekundy jednosci-pc.5




    $regfile = "M8def.dat"
    Dim Ktorywysw As Byte
    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte
    Dim Minutyjed As Byte
    Dim Minutydzies As Byte
    Dim Godzinyjed As Byte
    Dim Godzinydzies As Byte
    Dim Sekundyjed As Byte
    Dim Sekundydzies As Byte
    Dim Sekundy1 As Byte
    Dim Minuty1 As Byte
    Dim Godziny1 As Byte
    Dim Byt As Bit

    Declare Sub Odczyt
    Declare Sub Zapis


    Config Sda = Portd.0
    Config Scl = Portd.1
    Config Portc = Output : Portc = &B00000000
    Config Portb = Output
    Config Pinb.4 = 0
    Config Pinb.5 = 0

    Portb = &B11110000






    Config Timer0 = Timer , Prescale = 64 : Enable Interrupts : Enable Timer0
    On Timer0 Coms

    Przyciskgodz Alias Pinb.4
    Przyciskmin Alias Pinb.5

    Byt = 0
    Do
    If Przyciskgodz = 0 And Przyciskmin = 1 Then
    Byt = 1
    Incr Godziny
    Waitms 200
    If Godziny > 23 Then Godziny = 0
    If Przyciskgodz = 1 Then
    Godziny1 = Godziny
    Minuty1 = Minuty
    Sekundy1 = Sekundy
    Call Zapis
    Byt = 0
    End If
    End If
    If Przyciskmin = 0 And Przyciskgodz = 1 Then
    Byt = 1
    Incr Minuty
    Sekundy = 0
    Waitms 200
    If Minuty > 59 Then Minuty = 0
    If Przyciskmin = 1 Then
    Godziny1 = Godziny
    Minuty1 = Minuty
    Sekundy1 = Sekundy
    Call Zapis
    Byt = 0
    End If
    End If
    If Byt = 0 Then
    Call Odczyt
    End If
    Waitms 500
    Sekundyjed = Sekundy Mod 10
    Sekundydzies = Sekundy / 10
    Minutyjed = Minuty Mod 10
    Minutydzies = Minuty / 10
    Godzinyjed = Godziny Mod 10
    Godzinydzies = Godziny / 10
    Loop : End





    Coms:
    Incr Ktorywysw : If Ktorywysw = 6 Then Ktorywysw = 0
    Select Case Ktorywysw
    Case 0:
    Portb = Godzinydzies : Portc = &B00000001
    Case 1:
    Portb = Godzinyjed : Portc = &B00000010
    Case 2:
    Portb = Minutydzies : Portc = &B00000100
    Case 3:
    Portb = Minutyjed : Portc = &B00001000
    Case 4:
    Portb = Sekundydzies : Portc = &B00010000
    Case 5:
    Portb = Sekundyjed : Portc = &B00100000
    End Select
    Return







    'PROCEDURA ODCZYTU CZASU.'
    Sub Odczyt
       I2cstart                                                 'INICJALIZACJA MAGISTRALI I2C.'
       I2cwbyte 160                                             'PODANIE ADRESU DLA PCF 8583; ZAPIS.'
       I2cwbyte 2                                               'WYBÓR DRUGIEGO REJESTRU, REJESTR SEKUND.'
       I2cstart                                                 'POWTÓRNA INICJALIZACJA MAGISTRALI I2C.'
       I2cwbyte 161                                             'PODANIE ADRESU DLA PCF 8583; ODCZYT.'
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack                                    'ODCZYT MINUT Z POTWIERDZENIE TRANSMISJI.'
       I2crbyte Godziny , Nack                                  'ODCZYT GODZIN BEZ POTWIERDZENIA TRANSMISJI.'
       I2cstop                                                  'KONIEC TRANSMISJI I2C.'
    Sekundy = Makedec(sekundy)
    Minuty = Makedec(minuty)                                    'KONWERSJA MINUT Z LICZBY W FORMACIE BCD NA DEC.'
    Godziny = Makedec(godziny)                                  'KONWERSJA GODZIN Z LICZBY W FORMACIE BCD NA DEC.'
    End Sub




    'PROCEDURA ZMIANY CZASU.'
    Sub Zapis
    Sekundy1 = Makebcd(sekundy1)
    Minuty1 = Makebcd(minuty1)                                  'KONWERSJA MINUT Z LICZBY W FORMACIE DEC NA BCD.'
    Godziny1 = Makebcd(godziny1)                                'KONWERSJA GODZIN Z LICZBY W FORMACIE DEC NA BCD.'
       I2cstart                                                 'INICJALIZACJA MAGISTRALI I2C.'
       I2cwbyte 160                                             'PODANIE ADRESU DLA PCF 8583; ZAPIS.'
       I2cwbyte 0                                               'WYBRANIE PIERWSZEGO KONTROLNEGO REJESTRU.'
       I2cwbyte 8
       I2cstop
       I2cstart
       I2cwbyte 160                                             'USTAWIENIE TRYBU ZAPISU.'
       I2cwbyte 2                                               'WYBÓR DRUGIEGO REJESTRU, REJESTR SEKUND.'
       I2cwbyte Sekundy1                                        'ZAPIS SEKUND.'
       I2cwbyte Minuty1                                         'ZAPIS MINUT.'
       I2cwbyte Godziny1                                        'ZAPIS GODZIN.'
       I2cstop                                                  'KONIEC TRANSMISJI I2C.'
    End Sub



    Ustawianie czasu zrealizowane jest na dwóch przyciskach, niby wszystko działa ok ale czasami po ustawieniu czasu zegar stoi tak jakby RTC nie ruszył. Problem na pewno leży po stronie programu bo to nie pierwszy zegar z tym wsadem i takim problemem.
    Proszę o pomoc w znalezieniu błedu.
    Pozdrawiam.
  • #2
    mirekk36
    Level 42  
    Witam,

    Mam nadzieję, że piszesz programy z wcięciami a tutaj tylko przypadkowo wkleił ci się kod bez wcięć - bo masakrycznie się to czyta - nie tylko komuś ale i samemu można się pogubić na maxa, ale do rzeczy ....

    widzę, że odczyt robisz sobie w jakiejś tam procedurze i ok - skaczesz do tej procedury gdy twoja zmienna Byt = 0 . I jak się patrzy na ten sposób działania to można to można troszkę oczopląsu dostać - chyba może dochodzić do sytuacji gdy zmienna Byt - nigy nie będzie = 0 no i wtedy masz właśnie klops - bo zegarek jakby "stoi"

    Polecam ci sposób zawsze stosowany przeze mnie do tego typu zegarków. Jest o wiele bardziej niezawodny a na dodatek jak się już z nim oswoisz to okaże się prosty, łatwy i przyjemny

    Otóż ja zawsze wykorzystuję sygnał INT w jakimkolwiek układzie zegarkowym, który generuje mi przerwanie - najczęściej 1 na sekundę. Podłączam to wyjście z zegarka do dowolnego wejścia INT w procku. Procedura obsługi tegoż przerwania jest banalnie prosta i super krótka bo ustawia mi tylko i wyłącznie flagę na 1. Flaga ta służy do poinformowania "pętli głównej", że właśnie - można dokonać odczytu godziny z zegarka.

    Ma to tę ogromną zaletę w porównaniu do twojego sposobu, że ty czasem nawet kilka razy w ciągu sekundy odczytujesz ten czas (a przecież niepotrzebnie prawda?) .... i co więcej - u ciebie gdy patrzy się na tykające sekundy to na 100% czasem jest wrażenie, że niektóre sekundy trwają jakby troszkę dłużej albo troszkę krócej niż 1 sekunda - prawda?

    Gdy będziesz to robił w oparciu o przerwanie - to odczyt będzie dokładnie zsynchronizowany co 1 sekundę i nie będzie nigdy żadnych efektów ubocznych.

    Oczywiście w pętli głównej mogłoby to wyglądać mniej więcej tak:

    Code:
    Do
    
    ....
    ....
       If Flaga_Czas = 1 Then
           ..... tu skod do procedury odczytu czasu
           Flaga_Czas = 0
       Endif

    ....
    ....
    Loop


    jak widzisz trzeba pamiętać o zresetowaniu tejże flagi.

    Oczywiście jak sam się domyślasz bardzo łatwo wstrzymywać te odczyty gdy zajdzie taka potrzeba - za pomocą np jeszcze jakiejś innej zmiennej czy flagi itp
  • #3
    pier
    Level 23  
    Bardzo fajny ten Twój sposób odczytu, pewnie skorzystam z niego w kolejnej konstrukcji. Ale czy nie dało by się przerobić mojego programu żeby działał prawidłowo?
    Nie chciałbym już nic zmieniać a jedynie poprawić program.

    Ps. U mnie sekundy działają bardzo dobrze i nie ma efektu o którym Piszesz.
  • #4
    mirekk36
    Level 42  
    tak na szybko co mi przychodzi do głowy w tym co jest - to nie korzystasz w ogóle z Debounce czy tego mehanizmu - i gdy robisz np zapis - to może następuje próba wielkorotnego zapisu?

    poza tym po co za każdym razem zapisujesz coś do rejestru kontrolnego? przecież do niego wystarczy dokonać zapisu ustawień raz - przed wejściem do pętli głównej w twoim przypadku bo twoje użycie zegarka nie uzasadnia innego użycia tegoż rejestru - tzn tak mi się wydaje. Za to w procedurze zapisu masz tak na prawdę szybko dwa zapisy do zegarka , które jeszcze zwielokrotnione przez brak debounce - może powodują jakieś zakłócenie lub zawieszenie I2C ???

    tak tylko próbuję się czegoś domyślać