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

Atmega8 + PCF8583, wyświetlanie daty i godziny. Co jest źle?

gervee 08 Lis 2008 22:18 2825 6
  • #1 5716721
    gervee
    Specjalista Automatyk
    Witam!
    Wykonałem sobie prosty układ z Atmega8 i PCF8583. Do programowania używam BascomAVR. PCF podłączone ma wejście A0 do GND (więc adresy A0 - zapis i A1 - odczyt). Na wyświetlaczu LCD ma wyświetlać się data i czas. Mam problem z zapisem wartości początkowej od jakiej zegar powinien wystartować. W chwili obecnej używam takiego programu:

    
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    'deklaracja funkcji
    Declare Sub Odczytajczas()
    Declare Sub Ustawczas(Byval s1 As byte , Byval m1 As byte , Byval h1 As byte , Byval d1 As byte , Byval month1 As byte)
    
    'deklaracja zmiennych
    Dim s As Byte , m As Byte , h As Byte
    Dim d As Byte , month As Byte
    Dim wm As Byte , yd As Byte
    Dim a As Byte
    
    'konfiguracja pinów portów dla współpracy z LCD
    Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portb.2 , Rs = Portb.1
    Config Lcd = 16 * 2
    Cursor Off Noblink
    
    Config Pind.7 = Input
    
    Portd.7 = 1
    
    'konfiguracja portów do współpracy z I2C
    Config Scl = Portc.5
    Config Sda = Portc.4
    
    Cls
    
    I2cinit
    
    Lowerline
    Lcd "PCF8583 clock"
    Wait 2
    
    Do
       If Pind.7 = 0 Then
          Cls
          Lcd "* RESET ZEGARA *"
          Call Ustawczas(30 , 20 , 18 , 8 , 11)                 '<- nie chce tego wpisać ... dlaczego?
          Wait 2
          Cls
       End If
    
       Call Odczytajczas
       Waitms 100
    Loop
    End
    
    Sub Odczytajczas()
        I2cstart                                                'generowanie startu
        I2cwbyte &HA0                                           'wpisanie adresu PCF8583 do
    
        I2cwbyte 2                                              'wybranie drugiego rejestru
        I2cstart                                                'wygenerowanie powtórnego startu
        I2cwbyte &HA1
                                                   'zapis adresu do odczytu informacji
        I2crbyte S , Ack                                        'odczyt sekund
        I2crbyte M , Ack                                        'odczyt minut
        I2crbyte H , Ack                                        'odczyt godzin
        I2crbyte Yd , Ack                                       'odczyt roku i dni
        I2crbyte Wm , Nack                                      'odczyt tygodnia i miesiąca
        I2cstop                                                 'wygenerowanie stopu
    
        Lcd "Czas: " ; Bcd(h) ; ":" ; Bcd(m) ; ":" ; Bcd(s)
        Lowerline
        Lcd "Data: " ; "2008" ; "-" ; Bcd(wm) ; "-" ; Bcd(yd)
        Home Upper
    
    End Sub
    
    Sub Ustawczas(s1 As byte , m1 As byte , h1 As byte , d1 As byte , month1 As byte)
                                                                'ponieważ wartości są zapisywane jako BCD najpierw trzeba je przekonwertować
       s1 = Makebcd(s1)                                         'sekundy
       m1 = Makebcd(m1)                                         'minuty
       h1 = Makebcd(h1)                                         'godziny
       d1 = Makebcd(d1)                                         'dni
       month1 = Makebcd(month1)                                 'miesiące
    
       I2cstart                                                 'generowanie startu
       I2cwbyte &HA0
       I2cwbyte 0
       I2cwbyte 8
       I2cstop
       wait 1
    
       I2cstart
       I2cwbyte &HA0
       I2cwbyte 2
       I2cwbyte s1
       Cls
       Lcd "s1:" ; BCD(s1)
       Wait 1
       I2cwbyte m1
       Cls
       Lcd "m1:" ; BCD(m1)
       Wait 1
       I2cwbyte h1
       Cls
       Lcd "h1:" ; BCD(h1)
       Wait 1
       I2cwbyte d1
       Cls
       Lcd "d1:" ; BCD(d1)
       Wait 1
       I2cwbyte month1
       Cls
       Lcd "month1:" ; BCD(month1)
       Wait 1
       I2cstop
    
    End Sub
    
    


    Pod przycisk podpięta jest procedura, która powinna zapisać do rejestrów zegara PCF podane w niej wartości a nic takiego nie robi .... albo jestem ślepy i nie widzę gdzie popełniłem jakiś błąd.

    Dałem sobie wyświetlanie wartości na LCD, które powinny iść do zapisania zegara i co się okazuje ... pojawiają się tu jakieś bzdury np. S1: 59 (powinno być chyba 30)., M1:00, H1:00, d1:=:, month1:11

    W rezultacie na wyświetlaczu po naciśnięciu przycisku mam liczenie od 00:00:00 a nie tak jak chciałbym. Gdzie popełniam błąd?

    Może mi ktoś podesłać działający program - może mam uwalony zegar?
  • #2 5717009
    gregoorr
    Poziom 17  
    Zapisuje tak godzinę w zegarku NIXIE.
    Format zapisu AB:CD, czyli 23:30 to
    A=2
    B=3
    C=3
    D=0
    Dlatego że godzina jest ustawiana na poszczególnych lampach po kolei, tak dla bajeru.
    Rem * * * Przeliczenie i zapis Do Pcf * * *
    H = A
    Shift H , Left , 4
    H = H + B
    
    M = C
    Shift M , Left , 4
    M = M + D
    
    I2cstart
    I2cwbyte 162
    I2cwbyte 2
    I2cwbyte 0
    I2cwbyte M
    I2cwbyte H
    I2cstop


    Działa bez problemu.
    Odczytuje:
    Sub Odczytaj_godzine
    
    I2cstart
    I2cwbyte 162
    I2cwbyte 2
    I2cstart
    I2cwbyte 163
    I2crbyte S , Ack
    I2crbyte M , Ack
    I2crbyte H , Nack
    I2cstop
    
    F = S And &B00001111
    Shift S , Right , 4
    E = S
    
    
    B = H And &B00001111
    Shift H , Right , 4
    A = H
    
    D = M And &B00001111
    Shift M , Right , 4
    C = M
    
    End Sub


    Na lampach wyświetla:
    AB:CD:EF

    Może coś pomoże. Zakładam że od części elektryznej masz wszystko ok', bez podstawowych błędów setki razy opisywanych na elektrodzie.
  • #3 5717023
    dawid512
    Poziom 32  
    Zobacz tu zadeklarowałeś podprogram tak
    Declare Sub Ustawczas(Byval s1 As byte , Byval m1 As byte , Byval h1 As byte , Byval d1 As byte , Byval month1 As byte)
    


    A tutaj masz tak:
    Sub Ustawczas(s1 As byte , m1 As byte , h1 As byte , d1 As byte , month1 As byte) 
    Podpowiem byval.

    Nie dziw się że zobaczysz głupoty bo wyświetlasz sobie na lcd wartości zmiennych w postaci kodu bcd.
    Lcd "s1:" ; BCD(s1) 


    W odczycie też namieszałeś... Skoro zapisuje dane do pcf-a w postaci bcd to nie licz na to że odda ci dane w postaci dziesiętnej... Najpierw musisz je na nią zamienić tak:
  • #4 5718348
    zumek
    Poziom 39  
    gervee napisał:
    ...Może mi ktoś podesłać działający program - może mam uwalony zegar?

    Ależ Twój program jak najbardziej działa, tylko masz źle skonfigurowany kompilartor.
    Na początku kodu, dodaj 3 "magiczne zaklęcia" i powinno działać.
    Np.
    
    $hwstack = 32
    $swstack = 24
    $framesize = 32
    

    Piotrek

    PS
    dawid512 :arrow: Widzisz błędy tam, gdzie ich nie ma.
  • #5 5720032
    gervee
    Specjalista Automatyk
    Wielkie dzięki zumek! Jeszcze nie znam tego kompilatora ... sprawdzałem ustawienia i nic mnie nie zaniepokoiło (uznałem, że wszystko jest OK). Jednak nie wszystko było ... podany przez Ciebie wpis do programu załatwił wszystko.

    Pewnie chodziło o $swstack, który domyślnie w kompilatorze ustawiony jest na 8.
  • #7 5742819
    dawid512
    Poziom 32  
    Będą takie jakie wskaże Bascom po wybraniu uc :)
REKLAMA