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

Bascom 2.0.7.3, PCF8583, kompletny program - nie zapisuje dnia tygodnia i roku

propropro 21 Lis 2011 22:15 2038 2
  • #1 10167117
    propropro
    Poziom 10  
    Witam wszystkich serdecznie,
    kontynuując naukę napotkałem na problem, dziś dla mnie nie do rozwiązania. Poniższy kod kompiluje się poprawnie, wyświetla i umożliwia zmianę wszystkiego oprócz dnia tygodnia i roku. Kod analizowałem naprawdę setki razy i nic. Nie widzę błędu. Wstawiałem LCD tuż przed zapisem i tuż po odczycie. Wszystko wskazuje na to, że info o roku i dniu tygodnia nie jest zapisywane. Dlaczego ? Płytka EvB 4.3.
    Może któryś z szanownych forumowiczów zechciałby "rzucić okiem" na poniższy kod i wskazać błędy w rozumowaniu. Wiem, że temat był poruszany setki razy, ale takiego problemu wujek Google jeszcze nie widział :=).
    Pozdrawiam wszystkich czytających serdecznie.
    $regfile = "m644pdef.dat"
    $crystal = 16000000
    $baud = 19200
    $hwstack = 32
    $swstack = 50
    $framesize = 40
    Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.5 , Rs = Portb.6
    Config Lcd = 16 * 2
    
    Config Pinc.7 = Input                                       ' enter
    Config Pinc.6 = Input                                       ' up
    Config Pinc.5 = Input                                       ' down
    Config Pinc.4 = Input                                       ' cancel
    Config Pinc.3 = Input                                       ' save
    Set Portc.7
    Set Portc.6
    Set Portc.5
    Set Portc.4
    Set Portc.3
    S1 Alias Pinc.7
    S2 Alias Pinc.6
    S3 Alias Pinc.5
    S4 Alias Pinc.4
    S5 Alias Pinc.3
    
    Dim Cur_mode As Byte
    
    Cur_mode = 0
    Config Sda = Portc.1
    Config Scl = Portc.0
    
    I2cinit
    Waitms 1
    
    Dim Second As Byte
    Dim Minute As Byte
    Dim Hour As Byte
    Dim Day As Byte
    Dim Month As Byte
    Dim Year As Word
    Dim Weekday As Byte
    Dim Yearbase As Word
    Yearbase = 2008
    
    Dim Tmp As Byte
    Dim Tmp1 As Byte
    Declare Sub Gettime()
    Declare Sub Displaytime()
    Declare Sub Storetime(byval S As Byte , Byval M As Byte , Byval H As Byte , Byval D As Byte , Byval Mm As Byte , Byval Y As Word , Byval Dow As Byte)
    
    Declare Sub Settime()
    Declare Sub Cancel()
    Declare Sub Plus()
    Declare Sub Minus()
    Declare Sub Saveandexit()
    Declare Sub Enter()
    Cursor Off Noblink
    
    Cls
    '-------------------------------------------------------------------
    '                                  main
    '-------------------------------------------------------------------
    Do
       If Cur_mode = 0 Then
          Call Gettime
          Call Displaytime
       End If
       'Debounce S1 , 0 , Settime , Sub
       If S1 = 0 Then                                           ' enter
          Waitms 25
          If S1 = 0 Then
             Call Settime
          End If
       End If
    Loop
    End
    
    Sub Settime()  '-------------------------------------------------------------------
    Disable Interrupts
       Cur_mode = 0
       Locate 1 , 1
       Cursor On Blink
       Do
          Debounce S1 , 0 , Enter , Sub
          Debounce S2 , 0 , Plus , Sub
          Debounce S3 , 0 , Minus , Sub
          Debounce S4 , 0 , Cancel , Sub
          Debounce S5 , 0 , Saveandexit , Sub
          If Cur_mode = 0 Then
             Cursor Off Blink
             Exit Do
          End If
       Loop
    Enable Interrupts
    End Sub
    
    Sub Enter()  '-------------------------------------------------------------------
       Select Case Cur_mode
          Case 0:
             Locate 1 , 1
             Incr Cur_mode
          Case 1:
             Locate 1 , 4
             Incr Cur_mode
          Case 2:
             Locate 1 , 7
             Incr Cur_mode
          Case 3:
             Locate 2 , 1
             Incr Cur_mode
          Case 4:
             Locate 2 , 5
             Incr Cur_mode
          Case 5:
             Locate 2 , 8
             Incr Cur_mode
          Case 6:
             Locate 2 , 11
             Incr Cur_mode
          Case 7:
             Locate 1 , 1
             Cur_mode = 1
       End Select
    End Sub
    
    Sub Plus()  '-------------------------------------------------------------------
       Select Case Cur_mode
          Case 1:
             If Hour = 23 Then Hour = 0 Else Incr Hour
             Call Displaytime()
             Locate 1 , 1
          Case 2:
             If Minute = 59 Then Minute = 0 Else Incr Minute
             Call Displaytime()
             Locate 1 , 4
          Case 3:
             If Second = 59 Then Second = 0 Else Incr Second
             Call Displaytime()
             Locate 1 , 7
          Case 4:
             If Weekday = 6 Then Weekday = 0 Else Incr Weekday
             Call Displaytime()
             Locate 2 , 1
          Case 5:
             Tmp1 = Year Mod 4
             Tmp = Lookup(month , Monthlengths)
             If Tmp1 = 0 And Month = 2 Then Incr Tmp
             If Day = Tmp Then Day = 1 Else Incr Day
             Call Displaytime()
             Locate 2 , 5
          Case 6:
             If Month = 12 Then Month = 1 Else Incr Month
             Call Displaytime()
             Locate 2 , 8
          Case 7:
             Incr Year
             Call Displaytime()
             Locate 2 , 11
       End Select
    End Sub
    
    Sub Minus()   '-------------------------------------------------------------------
       Select Case Cur_mode
          Case 1:
             If Hour = 0 Then Hour = 23 Else Decr Hour
             Call Displaytime()
             Locate 1 , 1
          Case 2:
             If Minute = 0 Then Minute = 59 Else Decr Minute
             Call Displaytime()
             Locate 1 , 4
          Case 3:
             If Second = 0 Then Second = 59 Else Decr Second
             Call Displaytime()
             Locate 1 , 7
          Case 4:
             If Weekday = 0 Then Weekday = 6 Else Decr Weekday
             Call Displaytime()
             Locate 2 , 1
          Case 5:
             If Day = 1 Then
                   Day = Lookup(month , Monthlengths)
                   If Month = 2 Then
                      Tmp = Year Mod 4
                      If Tmp = 0 Then
                         Incr Day
                      End If
                   End If
             Else
                Decr Day
             End If
             Call Displaytime()
             Locate 2 , 5
          Case 6:
             If Month = 1 Or Month = 0 Then Month = 12 Else Decr Month
             Call Displaytime()
             Locate 2 , 8
          Case 7:
             Decr Year
             Call Displaytime()
             Locate 2 , 11
       End Select
    End Sub
    
    Sub Saveandexit()                                           '-------------------------------------------------------------------
       Call Storetime(second , Minute , Hour , Day , Month , Year , Weekday)
       Cur_mode = 0
    End Sub
    
    Sub Cancel()  '-------------------------------------------------------------------
       Cur_mode = 0
    End Sub
    
    Sub Gettime()  '-------------------------------------------------------------------
        I2cstart
         I2cwbyte 162
         I2cwbyte 2
         I2cstart
         I2cwbyte 163
         I2crbyte Second , Ack
         I2crbyte Minute , Ack
         I2crbyte Hour , Ack
         I2crbyte Day , Ack
         I2crbyte Month , Nack
        I2cstop
        Second = Makedec(second)
        Minute = Makedec(minute)
        Hour = Makedec(hour)
        Year = Day
        Shift Year , Right , 6
        Year = Makedec(year)
        Year = Year + Yearbase
        Day = Day And &B00111111
        Day = Makedec(day)
        Weekday = Month
        Shift Weekday , Right , 5
        Weekday = Makedec(weekday)
        Month = Month And &B00011111
        Month = Makedec(month)
    End Sub
    
    Sub Displaytime() '-------------------------------------------------------------------
       Locate 1 , 1
       If Hour < 10 Then Lcd "0" : Lcd Hour ; ":"
       If Minute < 10 Then Lcd "0" : Lcd Minute ; ":"
       If Second < 10 Then Lcd "0" : Lcd Second
       Locate 2 , 1
       Lcd Lookupstr(weekday , Weekdays) ; " "
       If Day < 10 Then Lcd "0" : Lcd Day ; "-"
       If Month < 10 Then Lcd "0" : Lcd Month ; "-" ; Year
    End Sub
    
     '-------------------------------------------------------------------
    Sub Storetime(s As Byte , M As Byte , H As Byte , D As Byte , Mm As Byte , Y As Word , Dow As Byte)
        S = Makebcd(s)
        M = Makebcd(m)
        H = Makebcd(h)
        D = Makebcd(d)
    
        Dim Yy As Byte
        Yy = Y Mod 4                                            ' wydlubujemy liczbe lat po roku przestępnym
        Yy = Makebcd(yy)
        Shift Yy , Left , 6                                     ' rok na swoje miejsce w bajcie
    
        D = D Or Yy                                             ' łączymy info  o dniach i roku
    
        Dow = Makebcd(dow)                                      ' day of week
        Shift Dow , Left , 5
        Mm = Makebcd(mm)
        Mm = Dow Or Mm                                          ' dow i month razem
        I2cstart                                                ' zapis
           I2cwbyte 162
           I2cwbyte 2
           I2cwbyte S
           I2cwbyte M
           I2cwbyte H
           I2cwbyte D
           I2cwbyte Mm
           I2cstop
    End Sub
    
    Weekdays:                                                '-------------------------------------------------------------------
    Data "Pon" , "Wto" , "Sro" , "Czw" , "Pt " , "Sob" , "Nie"
    
    Monthlengths:                                               '-------------------------------------------------------------------
    Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31
    

    P.S. Kod na szybko wycięty z większego.
  • #2 10167246
    Jaca
    Poziom 31  
    PCF8583 nie ma rejestru roku tak jak PCF8563. Co do dnia tygodnia - muszę poszukać w DS.

    EDIT:

    Dzień tygodnia musisz odczytać z rejestru miesiąca (06). Służą do tego bity 7..5 czyli:

    1. odczytać rejestr 06
    2. zamaskować wartość za pomocą AND &B11100000
    3. przesunąć w prawo o 5 (Shift Rejestr_06 , Right, 5)
  • #3 10168016
    propropro
    Poziom 10  
    Wiem, że PCF8583 nie ma rejestru roku - przeczytałem jego dokumentację.
    Wiem, że nie ma dedykowanego rejestru dnia tygodnia. Oba te problemy uwzględniłem w kodzie, co pokazałem w zamieszczonym źródle.Poniżej cytuję sam siebie:

    przy odczycie:

     Year = Day
        Shift Year , Right , 6
        Year = Makedec(year)
        Year = Year + Yearbase
        Day = Day And &B00111111
        Day = Makedec(day)
        Weekday = Month
        Shift Weekday , Right , 5
        Weekday = Makedec(weekday)
        Month = Month And &B00011111
        Month = Makedec(month) 


    przy zapisie:
           Dim Yy As Byte
        Yy = Y Mod 4          ' wydlubujemy liczbe lat po roku przestępnym
        Yy = Makebcd(yy)
        Shift Yy , Left , 6   ' rok na swoje miejsce w bajcie
    
        D = D Or Yy           ' łączymy info  o dniach i roku
    
        Dow = Makebcd(dow)    ' day of week
        Shift Dow , Left , 5
        Mm = Makebcd(mm)
        Mm = Dow Or Mm        ' dow i month razem 


    Problem jest taki, że powyższy program działa super z wyjątkiem tego, że gdy modyfikuję dzień tygodnia lub rok, wprowadzone przeze mnie zmiany nie są zapisywane w scalaku. Po wyświetleniu mam dalej poprzednią datę.godziny, minuty, sekundy, dni miesiąca i miesiące modyfikują się i zapisują ok. Wszystko wyświetlane (dekodowane) jest poprawnie.
    Na wyświetlaczu mam np.

    09:09:47
    Pon 22-11-2008


    Prośba o pomoc w odnalezieniu błędu w powyższym zacytowanym kodzie. Cały program umieściłem żeby można było CTRL-C i CTRL-V zrobić i wypróbować u siebie.
    - S1 - edycja czyli skakanie po kolejnych elementach do edycji
    - S2 - zmiany UP
    - S3 - Down
    - S4 - Escape
    - S5 - Save


    Scaliłem 2 posty.
    [zumek]


    EDIT:
    :=)
    Problem znikającego roku i dnia tygodnia rozwiązałem. Zapewne podczas zabaw, niechcący zupełnie ustawiłem trzeci bit rejestru kontrolnego. A bit ten odpowiada za...:

    mask flag:
    0 -> read locations 05 to 06 unmasked
    1 -> read date and month count directly

    Skutek? Nawet przy poprawnym zapisie roku i dnia tygodnia - w rejestrach 5 i 6 podczas odczytu ich nie było. Po wyzerowaniu bitu 3 w rejestrze kontrolnym, wszystko wróciło do normy. Problem udało się rozwiązać wyłącznie dzięki dokładnemu i ze zrozumieniem przeczytaniu dokumentacji PCF8583. Czego w przyszłości sobie i wszystkim innym początkującym serdecznie życzę.
    Pozdrawiam i temat zamykam
REKLAMA