Odczyt czasu w PCF 8563 - błędy


Witam
Mam płytkę Loggera GPS + SD + PCF8563. Jeśli chodzi o GPS i zapis na SD wszytko jest OK. Problemem jest ( i to pierwszy raz się z czymś takim stykam ) odczyt danych z z układu PCF8563.
Otóż dla pewnych wartości sekund, odczytana wartość czasu - godziny jest większa o 40 ( czterdzieści ).

Czyli jeśli czas jest
22:40:02
to jest wyświetlany poprawnie, ale jak jest
22:40:50
to wyświetla
62:40:50

Zauważyłem, że gdy sekundy są pomiędzy 40 a 0, to dodaje wartość 40 do wartości godzin. Właściwie nie dodaje tylko nagle taka wartość jest odczytana z rejestru układu PCF8563. Podobnie jest z dniem miesiąca - zamiast 16 stycznia jest 56 stycznia.

Dodam, że tego samego "sposobu" odczytu używam od kilku lat i jeszcze się nie spotkałem z takim problemem odczytu rejestru. Próbowałem z Atmega168 ( oczywiście nieco odchudziłem kod ) i efekt niestety ten sam. Podobnie a Atmega644P i 1284P, oczywiście po skonfigurowaniu portów.

$regfile = "m328pdef.dat"
$crystal = 8000000
$baud = 9600
$hwstack = 128
$swstack = 128
$framesize = 128
 
 
 
 
On Urxc Rs232_isr
Enable Urxc
 
Enable Interrupts
 
'********************* Konfiguracja wyświetlacza
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portd.7 , Rs = Portd.6
Config Lcd = 24 * 2
 
'********************* Konfiguracja znaków specjalnych LCD
Deflcdchar 1 , 2 , 5 , 5 , 2 , 32 , 32 , 32 , 32            ' symbol stopnia
Deflcdchar 2 , 4 , 4 , 4 , 32 , 32 , 32 , 32 , 32           ' symbol minuty
Deflcdchar 3 , 32 , 7 , 9 , 17 , 17 , 17 , 31 , 32          ' SD OK
 
'********** Konfiguracja Timer2  2 ms
Enable Timer0
Config Timer0 = Timer , Prescale = 64                       ' 1 sekunda = 500
 
On Timer0 Czas2
Timer0 = 6
 
Enable Interrupts
 
'**********
Config Clock = User
 
'********************* Konfiguracja magistrali I2C
 
Config Sda = Portc.4
Config Scl = Portc.5
Config I2cdelay = 10                                        ' domyślnie tryb Slow
I2cinit
 
'********************* Konfiguracja wejść i wyjść
 
Config Portb.1 = Output                                     ' podswietlanie LED
Set Portb.1
 
Config Portb.2 = Output                                     ' podswietlanie LED
Reset Portb.2
Led_p Alias Portb.2
 
Config Portd.4 = Input                                      ' "Control"
Set Portd.4
Ustaw Alias Pind.4
 
Config Portb.0 = Input                                      ' detekcja karty SD
Set Portb.0
Sd_det Alias Pinb.0
 
Config Portd.3 = Input                                      ' przycisk GSM
Set Portd.3
Gsm Alias Pind.3
 
 
'********************* dodawanie obsługi SD
$include "Config_MMCSD_HC.bas"
$include "CONFIG_AVR-DOS.bas"
 
'*********************  Deklaracje zmiennych karty SD
 
Dim Errorcode As Byte
Dim Blad_sd As Bit
Dim Zapisano As Bit
Dim Ciag_gps As String * 75
Dim Flaga_zapis_sd As Bit
Dim Czas_zapisu As Integer
 
'*********************  Deklaracje zmiennych dla UART
Dim Buffer As Byte
Dim Buffer_str As String * 10
Dim Sentence_header As String * 8
Dim Length As Byte
 
'*********************  Deklaracje zmiennych licznik
Dim Licznik_sd_lcd As Integer
Dim Flaga_sd As Bit
Dim Licznik_gsm As Long
Dim Flaga_gsm As Bit
Dim Licznik_przycisk As Byte
Dim Blokuj_przycisk As Bit
 
'*********************  Deklaracje zmiennych dla ramki GPRMC
Dim Gprmc_utc_string As String * 11
 
Dim Gprmc_status_string As String * 2
 
Dim Gprmc_lat_string As String * 10
Dim Gprmc_lathr_string As String * 2 : Dim Gprmc_lathr As Byte
Dim Gprmc_la_int As Integer
Dim Gprmc_latmin_string As String * 2 : Dim Gprmc_latmin As Byte
Dim Gprmc_latsec_string As String * 4 : Dim Gprmc_latsec As Byte
Dim Gprmc_latssec As Byte
 
Dim Gprmc_ns_string As String * 2
 
Dim Gprmc_lon_string As String * 11
Dim Gprmc_lonhr_string As String * 3 : Dim Gprmc_lonhr As Byte
Dim Gprmc_lo_int As Integer
Dim Gprmc_lonmin_string As String * 2 : Dim Gprmc_lonmin As Byte
Dim Gprmc_lonsec_string As String * 4 : Dim Gprmc_lonsec As Byte
Dim Gprmc_lonssec As Byte
 
Dim Gprmc_ew_string As String * 2
 
Dim Gprmc_speed_string As String * 5 : Dim Gprmc_speed As Word
Dim Speed As String * 5
Dim Speed_int As Integer
Dim Gprmc_course_string As String * 7 : Dim Gprmc_course As Word
Dim Course As String * 3
 
Dim Gprmc_date_string As String * 7
 
'*********************  Deklaracje zmiennych dla ramki GPGSV
Dim Gpgsv_totalmessages_string As String * 2 : Dim Total_messages As Byte
Dim Gpgsv_currentmessage_string As String * 2 : Dim Current_message As Byte
Dim Gpgsv_sats_string As String * 3
 
Dim Gpgsv_ch1satid_string As String * 3
Dim Gpgsv_ch1satel_string As String * 3
Dim Gpgsv_ch1sataz_string As String * 4
Dim Gpgsv_ch1satdb_string As String * 3
 
Dim La2 As String * 8
Dim Lo2 As String * 8
Dim La_oblicz As String * 10
Dim La_oblicz_number As Word
Dim Lo_oblicz As String * 10
Dim Lo_oblicz_number As Word
Dim Pozppv As Single
Dim Pozpph As Single
Dim Poz1 As String * 5
Dim Poz2 As String * 5
Dim Poz3 As String * 5
Dim Poz4 As String * 5
 
'********************* Deklaracje zmiennych zegara
Dim Dzien As Byte
Dim Miesiac As Byte
Dim Rok As Byte
Dim Godziny As Byte
Dim Godziny_lz As Byte
Dim Minuty As Byte
Dim Sekundy As Byte
Dim Dzien_tyg As Byte
 
Dim Sd_month As String * 4
Dim Sd_year As String * 4
 
Dim Dzien_bcd As Byte
Dim Miesiac_bcd As Byte
Dim Rok_bcd As Byte
Dim Godziny_bcd As Byte
Dim Minuty_bcd As Byte
Dim Sekundy_bcd As Byte
Dim Dzien_tyg_bcd As Byte
 
Dim Czas_pcf As String * 8                                  ' ciag - czas do zapisu na SD
Dim Data_pcf As String * 8                                  ' ciag - data do zapisu na SD
 
Dim Plik As String * 14                                     ' ciag nazwy pliku do zapisu na SD
Dim Data_plik As String * 6                                 ' ciag z numerem dnia i miesiaca
 
Dim Summer_time As Byte
Dim Summer_time1 As Byte
Dim Zmiana_czasu As Byte
Dim Lato_zima As Bit
Dim Pora_roku As Bit
 
'********************* Deklaracje zmiennych Timer2
Dim Licznik_sd As Integer
Dim Licznik_reset As Integer
Dim Licznik_zmien As Integer
Dim Flaga_lcd As Byte
 
'*********************
Declare Sub Nmea_parse()
Declare Sub Display_general_data()
Declare Sub Display_sat_data()
Declare Sub Maidenhead_calc()
Declare Sub Substract_data()
Declare Sub Display_direction()
 
Declare Sub Write_to_sd
Declare Sub Getdatetime
Declare Sub Settime_pcf
 
'********* odczyt z EEPROM Atmega wartosci zmiennej okreslajacej czas letni/zimowy
Readeeprom Zmiana_czasu , 40
 
Cursor Off Noblink
Cls
Call Getdatetime
 
Czas_zapisu = 3000
 
Do
 
   Call Maidenhead_calc()
 
   Call Substract_data()
 
 
   '******* zmiana na czas zimowy
If Zmiana_czasu = 0 Then
 If Lato_zima = 0 Then
   Decr Godziny
   Gosub Settime_pcf
   Zmiana_czasu = 1
   Writeeeprom Zmiana_czasu , 40
 End If
End If
 
'******* zmiana na czas letni
If Zmiana_czasu = 1 Then
 If Lato_zima = 1 Then
   Incr Godziny
   Gosub Settime_pcf
   Zmiana_czasu = 0
   Writeeeprom Zmiana_czasu , 40
 End If
End If
 
 
'***************************** uruchamianie zapisu
If Flaga_zapis_sd = 1 Then
 If Sd_det = 0 Then
'  If Gprmc_status_string = "A" Then
 '  If Speed_int > 0 Then
     Licznik_sd_lcd = 0
     Flaga_sd = 0
     Locate 2 , 12
     Lcd Chr(3)
     Led_p = 1
     Call Getdatetime
'     Gosub Write_to_sd
 '   End If
 ' End If
 End If
End If
 
If Flaga_sd = 1 Then
    Locate 2 , 12
    Lcd " "
    Led_p = 0
End If
 
 
'(
If Ustaw = 0 Then
 If Sd_det = 0 Then
    Call Getdatetime
    Licznik_sd_lcd = 0
    Flaga_sd = 0
    Locate 2 , 12
    Lcd Chr(3)
    Led_p = 1
    Gosub Write_to_sd
 End If
End If
')
 
'************* wysylanie przez gsm
If Gsm = 0 Then                                             ' po nacisnieciu przycisku
 If Blokuj_przycisk = 0 Then
    Blokuj_przycisk = 1
    Licznik_przycisk = 0
  Print "AT+CMGF=1" ; Chr(13) ;                             ' tryb tekstowy
  Waitms 300
  Print "AT+CMGS=" ; Chr(34) ; "+48664123456" ; Chr(34) ; " , 145 "       ' numer telefonu i okres waznosci SMS'a
  Waitms 300
  Print Czas_pcf ; " " ; Data_pcf                           ' godzina i data wyslania
  Print Str(gprmc_la_int) + "." + La2 + "," + Gprmc_ns_string       ' tresc SMS'a
  Print Str(gprmc_lo_int) + "." + Lo2 + "," + Gprmc_ew_string       ' tresc SMS'a
  Print "Predkosc: " ; Speed ; " km\h" ; Chr(26);           ' tresc SMS'a
 End If
End If
 
'************* wysylanie przez gsm
If Flaga_gsm = 1 Then                                       ' gdy flaga od licznika = 1 - co 5 minut
  Print "AT+CMGF=1" ; Chr(13) ;                             ' tryb tekstowy
  Waitms 300
  Print "AT+CMGS=" ; Chr(34) ; "+48664123456" ; Chr(34) ; " , 145 "       ' numer telefonu i okres waznosci SMS'a
  Waitms 300
  Print Czas_pcf ; " " ; Data_pcf                           ' godzina i data wyslania
  Print Str(gprmc_la_int) + "." + La2 + "," + Gprmc_ns_string       ' tresc SMS'a
  Print Str(gprmc_lo_int) + "." + Lo2 + "," + Gprmc_ew_string       ' tresc SMS'a
  Print "Predkosc: " ; Speed ; " km\h" ; Chr(26);           ' tresc SMS'a
  Flaga_gsm = 0
End If
 
 
'************* ustawianie reczne czasu
If Gsm = 0 Then
Sekundy = 0
Minuty = 44
Godziny = 22
Dzien = 16
Dzien_tyg = 5
Miesiac = 1
Rok = 15
Gosub Settime_pcf
End If
'(
')
 
 
'***************************** ustalenie czestotliwosci zapisu
If Speed_int > 0 And Speed_int =< 20 Then
   Czas_zapisu = 3000                                       '6 sekund
  Elseif Speed_int >= 21 And Speed_int =< 40 Then
  Czas_zapisu = 2500                                        '5 sekund
  Elseif Speed_int >= 41 And Speed_int =< 60 Then
  Czas_zapisu = 2000                                        '4 sekundy
  Elseif Speed_int >= 61 And Speed_int =< 80 Then
  Czas_zapisu = 1500                                        '3 sekundy
  Elseif Speed_int >= 81 Then
  Czas_zapisu = 1000                                        '2 sekundy
End If
 
'************
 
If Licznik_sd > Czas_zapisu Then
  Licznik_sd = 0
End If
 
 
Loop
End
 
 
'*********** odbior w przerwaniu
Rs232_isr:
 
Buffer = Ischarwaiting()
 
   If Buffer = 1 Then                                       'we got something
      Buffer = Waitkey()                                    'get it
 
 
      If Buffer = "$" Then
 
         Buffer_str = ""
 
         Do
            Buffer = Waitkey()
            Buffer_str = Buffer_str + Chr(buffer)
         Loop Until Buffer = ","
 
         Sentence_header = Buffer_str
 
         '*********** parsowanie dla GPRMC
         If Sentence_header = "GPRMC," Then
 
 
' $GPRMC,hhmmsss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh
'    |       |      |    |    |    |     |  |   |     |    |  |  |_ Checksum
'    |       |      |    |    |    |     |  |   |     |    |  |____ E or W
'    |       |      |    |    |    |     |  |   |     |    |_______ Magnetic variation, Degrees             : For example 156.4
'    |       |      |    |    |    |     |  |   |     |____________ Date, day,month,year                    : For example 150496(15 april 1996)
'    |       |      |    |    |    |     |  |   |__________________ Course over ground, degrees             : For example 340.5
'    |       |      |    |    |    |     |  |______________________ Speed over ground, knots                : For example 0.13
'    |       |      |    |    |    |     |_________________________ East/West indicator                     : For example E or W
'    |       |      |    |    |    |_______________________________ Longtitude, dddmm.mmmm                  : For example 00505.0505 (005.05.0505)
'    |       |      |    |    |____________________________________ North/South indicator                   : For example N or S
'    |       |      |    |_________________________________________ Latitude indicator                      : For example 5239.1920 (52.39.1920)
'    |       |      |______________________________________________ Data Validation indicator               : For example A=Data valid, V=Data invalid
'    |       |_____________________________________________________ Time, Hours,Minutes,Seconds,Subseconds  : For example 180442.453
'    |_____________________________________________________________ Message header ($GP)                    : For example ($GP)RMC = Recommended Minimum Specific GNSS Data
 
            Call Nmea_parse()
 
            Gprmc_utc_string = Buffer_str
            Length = Len(gprmc_utc_string) - 1
            Gprmc_utc_string = Left(gprmc_utc_string , Length)
 
            Call Nmea_parse()
 
            Gprmc_status_string = Buffer_str
            Length = Len(gprmc_status_string) - 1
            Gprmc_status_string = Left(gprmc_status_string , Length)       ' litera statusu A lub V
 
            Call Nmea_parse()
 
            Gprmc_lat_string = Buffer_str
            Length = Len(gprmc_lat_string) - 1
            Gprmc_lat_string = Left(gprmc_lat_string , Length)
 
            Call Nmea_parse()
 
            Gprmc_ns_string = Buffer_str
            Length = Len(gprmc_ns_string) - 1
            Gprmc_ns_string = Left(gprmc_ns_string , Length)       ' litera dlugosci geograficznej
 
            Call Nmea_parse()
 
            Gprmc_lon_string = Buffer_str
            Length = Len(gprmc_lon_string) - 1
            Gprmc_lon_string = Left(gprmc_lon_string , Length)
 
            Call Nmea_parse()
 
            Gprmc_ew_string = Buffer_str
            Length = Len(gprmc_ew_string) - 1
            Gprmc_ew_string = Left(gprmc_ew_string , Length)       ' litera szerokosci geograficznej
 
            Call Nmea_parse()
 
            Gprmc_speed_string = Buffer_str
            Length = Len(gprmc_speed_string) - 1
            Gprmc_speed_string = Left(gprmc_speed_string , Length)
 
            Call Nmea_parse()
 
            Gprmc_course_string = Buffer_str
            Length = Len(gprmc_course_string) - 1
            Gprmc_course_string = Left(gprmc_course_string , Length)
 
            Call Nmea_parse()
 
            Gprmc_date_string = Buffer_str
            Length = Len(gprmc_date_string) - 1
            Gprmc_date_string = Left(gprmc_date_string , Length)
 
 
         End If
         '----------------------------------------------------------------------
         '*********** parsowanie dla GPGSV
         If Sentence_header = "GPGSV," Then
 
 
            Call Nmea_parse()
 
            Gpgsv_totalmessages_string = Buffer_str
            Length = Len(gpgsv_totalmessages_string) - 1
            Gpgsv_totalmessages_string = Left(gpgsv_totalmessages_string , Length)
 
            Total_messages = Val(gpgsv_totalmessages_string)
 
            Call Nmea_parse()
 
            Gpgsv_currentmessage_string = Buffer_str
            Length = Len(gpgsv_currentmessage_string) - 1
            Gpgsv_currentmessage_string = Left(gpgsv_currentmessage_string , Length)
 
            Current_message = Val(gpgsv_currentmessage_string)
 
            Call Nmea_parse()
 
            Gpgsv_sats_string = Buffer_str
            Length = Len(gpgsv_sats_string) - 1
            Gpgsv_sats_string = Left(gpgsv_sats_string , Length)       ' ilosc satelitow
 
'*********** testowo inforamcja o satelitach
            If Val(gpgsv_sats_string) > 0 Then
 
                If Current_message = 1 Then
 
                  Call Nmea_parse()
 
                  Gpgsv_ch1satid_string = Buffer_str
                  Length = Len(gpgsv_ch1satid_string) - 1
                  Gpgsv_ch1satid_string = Left(gpgsv_ch1satid_string , Length)
 
                  Call Nmea_parse()
 
                  Gpgsv_ch1satel_string = Buffer_str
                  Length = Len(gpgsv_ch1satel_string) - 1
                  Gpgsv_ch1satel_string = Left(gpgsv_ch1satel_string , Length)
 
                  Call Nmea_parse()
 
                  Gpgsv_ch1sataz_string = Buffer_str
                  Length = Len(gpgsv_ch1sataz_string) - 1
                  Gpgsv_ch1sataz_string = Left(gpgsv_ch1sataz_string , Length)
 
                  Call Nmea_parse()
 
                  Gpgsv_ch1satdb_string = Buffer_str
                  Length = Len(gpgsv_ch1satdb_string) - 1
                  Gpgsv_ch1satdb_string = Left(gpgsv_ch1satdb_string , Length)
 
               End If
 
            End If
       End If
 
   End If
 
End If
 
 
 
Return
 
'*********** odbieranie kolejnych danych
Sub Nmea_parse()
 
            Buffer_str = ""
 
            Do
               Buffer = Waitkey()
               Buffer_str = Buffer_str + Chr(buffer)
            Loop Until Buffer = "," Or Buffer = "*"
 
            If Buffer_str = "," Then Buffer_str = ""
 
            If Buffer_str = "*" Then Buffer_str = ""
 
End Sub
 
'*********** obliczanie kursu na podstawie danych
Sub Display_direction
 
      If Gprmc_course => 0 And Gprmc_course < 12 Or Gprmc_course => 349 And Gprmc_course <= 360 Then
         Course = " N "
      Elseif Gprmc_course => 12 And Gprmc_course < 34 Then
         Course = "NNE"
      Elseif Gprmc_course => 34 And Gprmc_course < 56 Then
         Course = " NE"
      Elseif Gprmc_course => 56 And Gprmc_course < 79 Then
         Course = "ENE"
      Elseif Gprmc_course => 79 And Gprmc_course < 101 Then
         Course = " E "
      Elseif Gprmc_course => 101 And Gprmc_course < 124 Then
         Course = "ESE"
      Elseif Gprmc_course => 124 And Gprmc_course < 146 Then
         Course = " SE"
      Elseif Gprmc_course => 146 And Gprmc_course < 169 Then
         Course = "SSE"
      Elseif Gprmc_course => 169 And Gprmc_course < 191 Then
         Course = " S "
      Elseif Gprmc_course => 191 And Gprmc_course < 214 Then
         Course = "SSW"
      Elseif Gprmc_course => 214 And Gprmc_course < 236 Then
         Course = " SW"
      Elseif Gprmc_course => 236 And Gprmc_course < 259 Then
         Course = "WSW"
      Elseif Gprmc_course => 259 And Gprmc_course < 281 Then
         Course = " W "
      Elseif Gprmc_course => 281 And Gprmc_course < 304 Then
         Course = "WNW"
      Elseif Gprmc_course => 304 And Gprmc_course < 326 Then
         Course = " NW"
      Elseif Gprmc_course => 326 And Gprmc_course < 349 Then
         Course = "NNW"
      End If
 
End Sub
 
 
'*********** obliczanie wspolrzednych i predkosci
Sub Substract_data()
 
   Gprmc_lat_string = Left(gprmc_lat_string , 9)            ' ciag Latitude
   Gprmc_lon_string = Left(gprmc_lon_string , 10)           ' ciag Longitude
 
   Gprmc_lathr_string = Left(gprmc_lat_string , 2)          ' stopnie, bez przeliczania
   Gprmc_la_int = Val(gprmc_lathr_string)
   Gprmc_latmin_string = Mid(gprmc_lat_string , 3 , 2)      ' minuty
   Gprmc_latsec_string = Mid(gprmc_lat_string , 6 , 4)      ' sekundy
 
   Gprmc_lonhr_string = Left(gprmc_lon_string , 3)          ' stopnie, bez przeliczania
   Gprmc_lo_int = Val(gprmc_lonhr_string)
   Gprmc_lonmin_string = Mid(gprmc_lon_string , 4 , 2)      ' minuty
   Gprmc_lonsec_string = Mid(gprmc_lon_string , 7 , 4)      ' sekundy
 
   Gprmc_speed = Val(gprmc_speed_string)                    ' predkosc
   Gprmc_speed = Gprmc_speed * 1.852                        ' predkosc w km
   Speed = Str(gprmc_speed)
   Speed_int = gprmc_speed
   Gprmc_course = Val(gprmc_course_string)                  ' kurs w stopniach
 
 
End Sub
 
 
'*********** obliczanie
Sub Maidenhead_calc()
 
La_oblicz = Gprmc_latmin_string + Gprmc_latsec_string
Pozppv = Val(La_oblicz)                                      'pozycja V, konwersja string na liczbe
Pozppv = Pozppv / 60
La_oblicz = Fusing(pozppv , "#.##")                         'pozycja V
La_oblicz_number = Val(la_oblicz)
If La_oblicz_number < 10 Then                               ' gdy obliczona wartość mniejsza niz 1000
La_oblicz = "000" + La_oblicz                               ' dodawanie "000" przed ciagiem
Elseif La_oblicz_number < 100 Then
La_oblicz = "00" + La_oblicz                                ' dodawanie "00" przed ciagiem
Elseif La_oblicz_number < 1000 Then
La_oblicz = "0" + La_oblicz                                 ' dodawanie "0" przed ciagiem
Else
La_oblicz = La_oblicz
End If
Poz1 = Mid(la_oblicz , 1 , 4)                               'pozycja V
Poz2 = Mid(la_oblicz , 6 , 2)                               'pozycja V
La2 = Poz1 + Poz2                                           'pozycja V
 
'*****************************  obliczanie szerokości geograficznej
 
Lo_oblicz = Gprmc_lonmin_string + Gprmc_lonsec_string
Pozpph = Val(lo_oblicz)                                     'pozycja H, konwersja string na liczbe
Pozpph = Pozpph / 60                                        'pozycja H
Lo_oblicz = Fusing(pozpph , "#.##")                         'pozycja H
Lo_oblicz_number = Val(lo_oblicz)
If Lo_oblicz_number < 10 Then                               ' gdy obliczona wartość mniejsza niz 10
Lo_oblicz = "000" + Lo_oblicz                               ' dodawanie "000" przed ciagiem
Elseif Lo_oblicz_number < 100 Then                          ' gdy obliczona wartość mniejsza niz 100
Lo_oblicz = "00" + Lo_oblicz                                ' dodawanie "00" przed ciagiem
Elseif Lo_oblicz_number < 1000 Then                         ' gdy obliczona wartość mniejsza niz 1000
Lo_oblicz = "0" + Lo_oblicz                                 ' dodawanie "0" przed ciagiem
Else
Lo_oblicz = Lo_oblicz
End If
Poz3 = Mid(lo_oblicz , 1 , 4)                               'pozycja H
Poz4 = Mid(lo_oblicz , 6 , 2)                               'pozycja H
Lo2 = Poz3 + Poz4                                           'pozycja H
 
Call Display_general_data()
 
 
' wynik koncowy
'  stopnie           minuty  litera
' Gprmc_lathr_string + La2 + Gprmc_ns_string
' Gprmc_lonhr_string + Lo2 + Gprmc_ew_string
' predkosc
' Gprmc_speed
' kurs
' Course
' ilosc satelitow
' Gpgsv_sats_string
 
End Sub
 
 
 
Sub Display_general_data()
 
Call Display_direction()
 
Locate 1 , 1
Lcd Gprmc_speed ; " km/h    "
 
Locate 1 , 10
Lcd Course
 
Locate 2 , 1
'Lcd "Sig" ; Gpgsv_ch1satdb_string ; " "
Lcd Czas_pcf
 
'Locate 2 , 7
'Lcd "Sat" ; Gpgsv_sats_string ; " "
 
 
 
'********* wspolrzedne
Locate 1 , 13
Lcd Gprmc_la_int ; Chr(1) ; La2 ; Chr(2) ; Gprmc_ns_string ; " "
 
Locate 2 , 13
Lcd Gprmc_lo_int ; Chr(1) ; Lo2 ; Chr(2) ; Gprmc_ew_string  ; " "
 
End Sub
 
 
 
'***********************  Obsługa  karty SD
Sub Write_to_sd:
 
Call Getdatetime
Mmc_cs = 0
Sd_year = "20" + Str(rok)                                   ' aktualny rok z przedrostkiem '20'
Sd_month = Str(miesiac)                                     ' aktualny miesiac
Ciag_gps = Data_pcf + " " + Czas_pcf + " " + Str(gprmc_la_int) + "." + La2 + "," + Gprmc_ns_string + " , " + Str(gprmc_lo_int) + "." + Lo2 + "," + Gprmc_ew_string + ", " + Speed + " km\h " + Course
 
'*********************** procedura zapisu na SD  - inicjowanie karty SD
                                                  ' aktywacja karty SD
    Gbdriveerror = Driveinit()
    If Gbdriveerror = 0 Then
      Errorcode = Initfilesystem(1)
      If Errorcode <> 0 Then
         Blad_sd = 1
      Else
'************ Zapis pierwszego pliku
         Waitms 5
         Chdir Sd_year                                      ' zmien na podkatalog sd_year  - numer roku
         Waitms 5
         Chdir Sd_month                                     ' zmien na podkatalog sd_month - numer miesiaca
         Waitms 5
         Open Plik For Append As #2                         'otwórz plik trasy.txt aby dopisać dane
         Write #2 , Ciag_gps                                'zapisz dane: data, czas , odczyt temperatury
         Flush #2
         Close #2                                           'zamknij kanał transmisji sprzętowego urządzenia
         Chdir "\"                                          ' przejdz do glownego katalogu na karcie SD
        Blad_sd = 0                                         'ustaw zmienna na 0
       Zapisano = 1
     End If
    Else
      Blad_sd = 1
   End If
Mmc_cs = 1
Flaga_zapis_sd = 0
 
 
End Sub
 
'***********************  Obsługa czasu/daty
Sub Getdatetime:
 
'Disable Interrupts
  I2cstart
  I2cwbyte 162
  I2cwbyte &H02
  I2crepstart
  I2cwbyte 163
   I2crbyte Sekundy_bcd , Ack                                   'Odczytuje sekundy
   I2crbyte Minuty_bcd , Ack                                'Odczytuje minuty
   I2crbyte Godziny_bcd , Ack                                   'Odczytuje godziny
   I2crbyte Dzien_bcd , Ack                                     'Odczytuje dni
   I2crbyte Dzien_tyg_bcd , Ack                                 'Odczytuje dzień tygodnia
   I2crbyte Miesiac_bcd , Ack                                   'Odczutuje miesiąc
   I2crbyte Rok_bcd , Nack                                      'Odczytuje rok
   I2cstop
'Enable Interrupts
    Sekundy = Sekundy And &B01111111                        'sekundy
    Minuty = Minuty And &B01111111                          'minuty
    Godziny = Godziny And &B00111111                        'godziny
    Dzien = Dzien And &B00111111                            'dni miesiąca
    Dzien_tyg = Dzien_tyg And &B00000111                    'dni tygodnia
    Miesiac = Miesiac And &B00011111                        'miesiące
    Rok = Rok And &B11111111                                'lata
 
 
Sekundy = Makedec(sekundy_bcd)
Minuty = Makedec(minuty_bcd)
Godziny = Makedec(godziny_bcd)
Dzien = Makedec(dzien_bcd)
Miesiac = Makedec(miesiac_bcd)
Dzien_tyg = Makedec(dzien_tyg_bcd)
Rok = Makedec(rok_bcd)
 
 
   Czas_pcf = Bcd(godziny_bcd) + ":" + Bcd(minuty_bcd) + ":" + Bcd(sekundy_bcd)       'Tworzenie stringa z czasem
   Data_pcf = Bcd(dzien_bcd) + "/" + Bcd(miesiac_bcd) + "/" + Bcd(rok_bcd)       'Tworzenie stringa z data
 
Godziny_lz = Godziny
'*********************  obliczenia zmiennej pomocniczej
Summer_time1 = 31 - Dzien
Summer_time1 = Summer_time1 + Dzien_tyg
Summer_time = Summer_time1 Mod 7
Summer_time = 31 - Summer_time
 
'********************* obliczenia dla czasu letniego, pozostaly to czas zimowy
'********************* zmiana - na zimowy o godzinie 3, na letni o godzinie 2
If Miesiac >= 3 And Miesiac =< 10 Then
 If Miesiac = 3 And Dzien > Summer_time Then                ' dni marca po ostaniej niedzieli
    Lato_zima = 1
 Elseif Miesiac = 3 And Dzien = Summer_time And Godziny_lz > 1 Then       ' ostatnia niedziela marca, po godzinie 2.00
    Lato_zima = 1
 Elseif Miesiac = 10 And Dzien < Summer_time Then           ' dni pazdziernika przed ostatnia niedziela
    Lato_zima = 1
 Elseif Miesiac = 10 And Dzien = Summer_time And Godziny_lz < 3 Then       ' ostatnia niedziela pazdziernika, przed godzina 3.00
    Lato_zima = 1
    Pora_roku = 0
    Else
    Lato_zima = 0
 End If
End If
 
If Lato_zima = 0 Then
   Pora_roku = 1
   Else
   Pora_roku = 0
End If
 
 
 
End Sub
 
 
 
'********************* Funkcja ustawiająca zegar PCF8563
Sub Settime_pcf:
 
Sekundy_bcd = Makebcd(sekundy)
Minuty_bcd = Makebcd(minuty)
Godziny_bcd = Makebcd(godziny)
Dzien_bcd = Makebcd(dzien)
Dzien_tyg_bcd = Makebcd(dzien_tyg)
Miesiac_bcd = Makebcd(miesiac)
Rok_bcd = Makebcd(rok)
 
 
  I2cstart                                                  'warunek startu
    I2cwbyte &HA2                                           'Adres zapisu
    I2cwbyte 0                                              'select control register
    I2cwbyte 8                                              'ustaw bit maskowania dni i roku
    I2cstart                                                'powtórz warunek startu
    I2cwbyte &HA2                                           'Adres zapisu
    I2cwbyte 2                                              'wybór rejestru
     I2cwbyte Sekundy_bcd                                   'zapis sekund
     I2cwbyte Minuty_bcd                                    'zapis minut
     I2cwbyte Godziny_bcd                                   'zapis godzin
     I2cwbyte Dzien_bcd                                     'zapis dni
     I2cwbyte Dzien_tyg_bcd                                 'zapis dni tygodnia
     I2cwbyte Miesiac_bcd                                   'zapis miesięcy
     I2cwbyte Rok_bcd                                       'zapis roku
  I2cstop
End Sub
 
 
 
'*********************  Timer2 - 2 ms x 500 = 1 sekunda
 
Czas2:
Timer0 = Timer0 + 6
 
Incr Licznik_sd
Incr Licznik_zmien
Incr Licznik_sd_lcd
Incr Licznik_gsm
Incr Licznik_przycisk
 
If Licznik_sd = Czas_zapisu Then
   Flaga_zapis_sd = 1
   Licznik_sd = 0
End If
 
If Licznik_zmien = 1500 Then                                ' co 3 sekundy
   Incr Flaga_lcd
   Licznik_zmien = 0
End If
 
If Licznik_sd_lcd = 500 Then
   Flaga_sd = 1
End If
 
If Licznik_gsm = 150000 Then
   Flaga_gsm = 1
   Licznik_gsm = 0
End If
 
If Licznik_przycisk = 250 Then
   Blokuj_przycisk = 0
End If
 
Return