Witam serdecznie.
Mikrokontrolerami i w ogóle programowaniem bawię się od niedawna, dlatego też zamieszczony przeze mnie program na pewno nie wygląda zbyt estetycznie i na pewno też nie wykorzystuje pamięci w ekonomiczny sposób, ale nie chodzi o sam program, lecz o sposób naliczania sekund. Dlaczego w programie (poniżej) jest tak, że nie każda sekunda jest sobie równa? Tzn. dlaczego jeśli zegar wskazuje godziny z przedziału mniej więcej 22:00-00:00 zegar idzie mniej więcej idealnie, a w przedziale 00:00 - 06:00 przyspiesza się o około 10 sekund (sekundy w godzinach porannych są najkrótsze, w godzinach południowych trochę dłuższe, w popołudniowych jeszcze dłuższe a w nocnych przed północą najdłuższe)???
Wydawało mi się, że przerwania z wykorzystaniem timer1 działają w ten sposób, że po przerwaniu wykonywane są procedury "po przerwaniu" u mnie "czas", w tym czasie timer1 wykorzystywany jako licznik już zlicza przeskalowane (1024-krotnie) uderzenia kwarcu , a następnie liczy do 7909 (to miało się równać 1 sekundzie) i że obojętnie ile czasu zajmuje wykonanie procedury "czas" (aby poniżej 1 sekundy), to zawsze przerwania będą występowały co taki sam okres czasu (u mnie 1 sekunda).
Inaczej ujmując, jeśli procedura "czas" zajmie 1000 licznika, to ten policzy jeszcze 6909 i nastąpi przerwanie, jeśli procedura "czas" zajmie 1500 licznika, to ten policzy jeszcze 6409 i nastąpi przerwanie, tak czy tak przerwanie powinno być chyba co 7909 licznika. Dlaczego więc u mnie nie wygląda to tak w praktyce?
Serdecznie dziękuję i pozdrawiam
Mikrokontrolerami i w ogóle programowaniem bawię się od niedawna, dlatego też zamieszczony przeze mnie program na pewno nie wygląda zbyt estetycznie i na pewno też nie wykorzystuje pamięci w ekonomiczny sposób, ale nie chodzi o sam program, lecz o sposób naliczania sekund. Dlaczego w programie (poniżej) jest tak, że nie każda sekunda jest sobie równa? Tzn. dlaczego jeśli zegar wskazuje godziny z przedziału mniej więcej 22:00-00:00 zegar idzie mniej więcej idealnie, a w przedziale 00:00 - 06:00 przyspiesza się o około 10 sekund (sekundy w godzinach porannych są najkrótsze, w godzinach południowych trochę dłuższe, w popołudniowych jeszcze dłuższe a w nocnych przed północą najdłuższe)???
Wydawało mi się, że przerwania z wykorzystaniem timer1 działają w ten sposób, że po przerwaniu wykonywane są procedury "po przerwaniu" u mnie "czas", w tym czasie timer1 wykorzystywany jako licznik już zlicza przeskalowane (1024-krotnie) uderzenia kwarcu , a następnie liczy do 7909 (to miało się równać 1 sekundzie) i że obojętnie ile czasu zajmuje wykonanie procedury "czas" (aby poniżej 1 sekundy), to zawsze przerwania będą występowały co taki sam okres czasu (u mnie 1 sekunda).
Inaczej ujmując, jeśli procedura "czas" zajmie 1000 licznika, to ten policzy jeszcze 6909 i nastąpi przerwanie, jeśli procedura "czas" zajmie 1500 licznika, to ten policzy jeszcze 6409 i nastąpi przerwanie, tak czy tak przerwanie powinno być chyba co 7909 licznika. Dlaczego więc u mnie nie wygląda to tak w praktyce?
Program:
$regfile = "m32def.dat"
$crystal = 8000000
$baud = 19200
$hwstack = 32
$swstack = 10
$framesize = 40
'DEFINICJA ZNAKÓW (Ś, Ć, Ę, Ł, "stopień")
Deflcdchar 4 , 32 , 32 , 14 , 17 , 31 , 16 , 14 , 2
Deflcdchar 3 , 12 , 4 , 6 , 4 , 12 , 4 , 14 , 32
Deflcdchar 2 , 2 , 4 , 14 , 16 , 16 , 17 , 14 , 32
Deflcdchar 1 , 2 , 4 , 14 , 16 , 14 , 1 , 30 , 32
Deflcdchar 5 , 4 , 10 , 4 , 32 , 32 , 32 , 32 , 32
'KONFIGURACJA ADC ORAZ LCD
Config Adc = Single , Prescaler = Auto , Reference = Internal
Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.5 , Rs = Portb.6
Config Lcd = 20 * 4
Cls
Cursor Off Noblink
'WŁĄCZENIE ZASILANIA PRZETWORNIKA ADC
Start Adc
'KONFIGURACJA PORTÓW JAKO WEJŚCIA I PODCIĄGNIĘCIE DO LOGICZNYCH JEDYNEK
Ddrc = 0
Ddrd = 0
Portc = 255
Portd = 255
'ZMIENNE CZASU
Dim Sekunda As Byte
Dim Minuta As Byte
Dim Godzina As Byte
Dim Sekunda_1 As String * 2
Dim Minuta_1 As String * 2
Dim Godzina_1 As String * 2
Dim Dzien As Byte
Dim Miesiac As Byte
Dim Rok As Word
Dim Dzien_1 As String * 2
Dim Miesiac_1 As String * 2
Dim Rok_1 As String * 4
Dim Przestepnosc As Byte
Dim Dzien_tyg As Byte
Dim Dzien_tyg_1 As String * 4
'ZADANIE POCZATKOWYCH WARTOSCI DATY I CZASU
Sekunda = 0
Minuta = 0
Godzina = 0
Dzien = 1
Miesiac = 1
Rok = 2009
Dzien_tyg = 7
'ZMIENNE POMIARU TEMPERATURY I CIŚNIENIA
Dim U As Integer
Dim Temp As Single
Dim Temp_1 As Long
Dim Temp_2 As String * 5
Dim C As Integer
Dim W As Integer
Dim Cisnienie As Long
Dim V As Integer
Dim Cisnienie_1 As Single
Dim Cisnienie_2 As String * 6
'KONFIGURACJA TIMERA
Config Timer1 = Timer , Prescale = 1024
On Ovf1 Czas
Load Timer1 , 7909
Enable Timer1
Enable Interrupts
'FORMATOWANIE ZMIENNYCH ŻEBY ZAWSZE MIAŁY TĘ SAMĄ DŁUGOŚĆ NA WYŚWIETLACZU
Sekunda_1 = Str(sekunda)
Minuta_1 = Str(minuta)
Godzina_1 = Str(godzina)
Sekunda_1 = Format(sekunda_1 , "00")
Minuta_1 = Format(minuta_1 , "00")
Godzina_1 = Format(godzina_1 , "00")
Dzien_1 = Str(dzien)
Miesiac_1 = Str(miesiac)
Rok_1 = Str(rok)
Dzien_1 = Format(dzien_1 , "00")
Miesiac_1 = Format(miesiac_1 , "00")
Rok_1 = Format(rok_1 , "0000")
If Dzien_tyg = 1 Then
Dzien_tyg_1 = " pon"
Elseif Dzien_tyg = 2 Then
Dzien_tyg_1 = " wto"
Elseif Dzien_tyg = 3 Then
Dzien_tyg_1 = " sro"
Elseif Dzien_tyg = 4 Then
Dzien_tyg_1 = " czw"
Elseif Dzien_tyg = 5 Then
Dzien_tyg_1 = " pią"
Elseif Dzien_tyg = 6 Then
Dzien_tyg_1 = " sob"
Elseif Dzien_tyg = 7 Then
Dzien_tyg_1 = " nie"
End If
'NIESKOŃCZONA PĘTLA PRZERYWANA TYLKO PO UPŁYWIE 1 SEKUNDY
Do
Loop
'INSTRUKCJE, KTÓRE MAJĄ BYĆ WYKONANE PO UPŁYWIE 1 SEKUNDY
Czas:
Load Timer1 , 7909
' PRZELICZENIE CZASU PO UPŁYWIE 1 SEKUNDY
End If
Incr Sekunda
If Sekunda >= 60 Then
Sekunda = 0
Incr Minuta
End If
If Minuta >= 60 Then
Minuta = 0
Incr Godzina
End If
If Godzina >= 24 Then
Godzina = 0
Incr Dzien
Incr Dzien_tyg
End If
If Dzien_tyg > 7 Then
Dzien_tyg = 1
End If
If Miesiac = 1 Or Miesiac = 3 Or Miesiac = 5 Or Miesiac = 7 Or Miesiac = 8 Or Miesiac = 10 Or Miesiac = 12 Then
If Dzien > 31 Then
Dzien = 1
Incr Miesiac
End If
Elseif Miesiac = 4 Or Miesiac = 6 Or Miesiac = 9 Or Miesiac = 11 Then
If Dzien > 30 Then
Dzien = 1
Incr Miesiac
End If
End If
If Rok = 2012 Or Rok = 2016 Or Rok = 2020 Or Rok = 2024 Then
If Miesiac = 2 Then
If Dzien > 29 Then
Dzien = 1
Incr Miesiac
End If
End If
Elseif Miesiac = 2 Then
If Dzien > 28 Then
Dzien = 1
Incr Miesiac
End If
End If
If Miesiac > 12 Then
Miesiac = 1
Incr Rok
End If
Sekunda_1 = Str(sekunda)
Minuta_1 = Str(minuta)
Godzina_1 = Str(godzina)
Sekunda_1 = Format(sekunda_1 , "00")
Minuta_1 = Format(minuta_1 , "00")
Godzina_1 = Format(godzina_1 , "00")
Dzien_1 = Str(dzien)
Miesiac_1 = Str(miesiac)
Rok_1 = Str(rok)
Dzien_1 = Format(dzien_1 , "00")
Miesiac_1 = Format(miesiac_1 , "00")
Rok_1 = Format(rok_1 , "0000")
If Dzien_tyg = 1 Then
Dzien_tyg_1 = " pon"
Elseif Dzien_tyg = 2 Then
Dzien_tyg_1 = " wto"
Elseif Dzien_tyg = 3 Then
Dzien_tyg_1 = " śro"
Elseif Dzien_tyg = 4 Then
Dzien_tyg_1 = " czw"
Elseif Dzien_tyg = 5 Then
Dzien_tyg_1 = " pią"
Elseif Dzien_tyg = 6 Then
Dzien_tyg_1 = " sob"
Elseif Dzien_tyg = 7 Then
Dzien_tyg_1 = " nie"
End If
'DOKONANIE POMIARU CISNIENIA I TEMPERATURY
Temp_1 = 0
For C = 1 To 1000
U = Getadc(3)
U = Getadc(3)
Temp_1 = Temp_1 + U
Next
Temp = Temp_1 / 2803
Temp = Temp
Temp_2 = Fusing(temp , "#.#" )
Temp_2 = Format(temp_2 , " 000")
Cisnienie = 0
For V = 1 To 1000
W = Getadc(1)
W = Getadc(1)
Cisnienie = Cisnienie + W
Next
Cisnienie_1 = Cisnienie \ 1500
Cisnienie_1 = Cisnienie_1 + 929
Cisnienie_2 = Fusing(cisnienie_1 , "#.#")
Cisnienie_2 = Format(cisnienie_2 , " ")
'WYŚWIETLENIE NOWEGO CZASU I WARTOŚCI CISNIENIA I TEMPWRATURY NA WYŚWIETLACZU LCD
Locate 1 , 1
Lcd "czas: " ; Godzina_1 ; ":" ; Minuta_1 ; ":" ; Sekunda_1
Locate 2 , 1
Lcd "data: " ; Rok_1 ; "-" ; Miesiac_1 ; "-" ; Dzien_1 ; Dzien_tyg_1
Locate 3 , 1
Lcd "Ci" ; Chr(1) ; "nienie:" ; Cisnienie_2 ; " hPa"
Locate 4 , 1
Lcd "Temperatura: " ; Temp_2 ; Chr(5) ; "C"
Return
End
Serdecznie dziękuję i pozdrawiam