Problem z zapisem do eeprom więcej niż 2 zmiennych
: 12 mar 2017, 19:13
Witam Wszystkich
Mam pewien problem z częściowo nie działającym programem do zegarka w moim samochodzie.
Opiszę w skrócie jak działa mój układ.
Sercem układu jest Atmega16 taktowana zewnętrznym kwarcem 11.0592MHz, po szynie I2C podpięty jest zegarek PCF8583 oraz pamięć eeprom 24C02.
Do UART podłączony jest moduł bluetooth BTM222 służący do komunikacji urządzenia ze smartfonem.
Urządzenie wyświetla na LCD 2x16 znaków datę i godzinę, po naciśnięciu przycisku program przeskakuje na drugi ekran, gdzie wyświetla się temperatura in/out, po kolejnym naciśnięciu przycisku pojawia się kolejny ekran, na którym wyświetlane jest napięcie instalacji samochodowej. Ponowne naciśnięcie przycisku powoduje powrót do ekranu głównego z godziną i datą.
Aplikację na smartfona napisałem w AppInventor i działa poprawnie. Ustawienie godziny i daty działa, zapisanie stanu led do pamięci eeprom również działa.
Wymyśliłem sobie, że dodatkowo w celach edukacyjnych spróbuję zapisywać do pamięci eeprom - datę przeglądu technicznego ( w programie zmienne C wysyła datę do smartfona, a zmienna Q zapisuje datę w eeprom) i również to działa.
Postanowiłem pójść krok dalej i spróbować zapisać kolejne zmienne w eeprom - datę wymiany oleju silnikowego (w programie zmienne A oraz B), a także datę końca ubezpieczenia OC (zmienne I oraz K).
Daty wprowadzam w aplikacji na smartfonie, wysyłam je do układu, odczyt danych również odbywa się w aplikacji na smartfonie. Niestety próby zapisu zmiennych wymiany oleju silnikowego i OC nie działają.
Format daty, którą wysyłam z aplikacji do procka, to np.: 12-03-2017
W sumie leci: Q12-03-2017 i na końcu 10 oraz 13
Jeśli chcę, odczytać tą datę, to wysyłam do procka zmienną C i 1.
Do procka leci: C1 i na końcu 10 oraz 13
Kolejne zmienne zapisuję w analogiczny sposób, ale one już nie działają.
W załączeniu przesyłam kod z głównego pliku:
Bardzo proszę Was o pomoc w rozwiązaniu tego problemu. Jeśli coś niejasno opisałem, to piszcie.
Mam pewien problem z częściowo nie działającym programem do zegarka w moim samochodzie.
Opiszę w skrócie jak działa mój układ.
Sercem układu jest Atmega16 taktowana zewnętrznym kwarcem 11.0592MHz, po szynie I2C podpięty jest zegarek PCF8583 oraz pamięć eeprom 24C02.
Do UART podłączony jest moduł bluetooth BTM222 służący do komunikacji urządzenia ze smartfonem.
Urządzenie wyświetla na LCD 2x16 znaków datę i godzinę, po naciśnięciu przycisku program przeskakuje na drugi ekran, gdzie wyświetla się temperatura in/out, po kolejnym naciśnięciu przycisku pojawia się kolejny ekran, na którym wyświetlane jest napięcie instalacji samochodowej. Ponowne naciśnięcie przycisku powoduje powrót do ekranu głównego z godziną i datą.
Aplikację na smartfona napisałem w AppInventor i działa poprawnie. Ustawienie godziny i daty działa, zapisanie stanu led do pamięci eeprom również działa.
Wymyśliłem sobie, że dodatkowo w celach edukacyjnych spróbuję zapisywać do pamięci eeprom - datę przeglądu technicznego ( w programie zmienne C wysyła datę do smartfona, a zmienna Q zapisuje datę w eeprom) i również to działa.
Postanowiłem pójść krok dalej i spróbować zapisać kolejne zmienne w eeprom - datę wymiany oleju silnikowego (w programie zmienne A oraz B), a także datę końca ubezpieczenia OC (zmienne I oraz K).
Daty wprowadzam w aplikacji na smartfonie, wysyłam je do układu, odczyt danych również odbywa się w aplikacji na smartfonie. Niestety próby zapisu zmiennych wymiany oleju silnikowego i OC nie działają.
Format daty, którą wysyłam z aplikacji do procka, to np.: 12-03-2017
W sumie leci: Q12-03-2017 i na końcu 10 oraz 13
Jeśli chcę, odczytać tą datę, to wysyłam do procka zmienną C i 1.
Do procka leci: C1 i na końcu 10 oraz 13
Kolejne zmienne zapisuję w analogiczny sposób, ale one już nie działają.
W załączeniu przesyłam kod z głównego pliku:
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- $regfile = "m16adef.dat" ' Typ procesora
- $baud = 19200
- $crystal = 11059200
- $hwstack = 64
- $swstack = 64
- $framesize = 64
- Echo Off
- Config Submode = New
- Const Addressw = 168
- Const Addressr = 169
- Config Twi = 100000
- ' Konfiguracja LCD 2X16
- Config Lcdpin = Pin , E = Portb.0 , Rs = Portb.1 , Db7 = Portb.2 , Db6 = Portb.3 , Db5 = Portb.4 , Db4 = Portb.5 , Wr = Portb.6
- Config Lcd = 16x2 'nowy sposob zapisu
- Cursor Off
- Cls
- ' Zezwolenie na przerwanie zewnętrzne
- Enable Interrupts
- 'Konfiguracja TIMERA do obsługi UART
- Config Timer1 = Timer , Prescale = 256 , Compare_a = Disconnect , Compare_b = Disconnect , Clear Timer = 1
- Enable Compare1a : On Compare1a Przerwanie : Compare1a = 43199
- Dim 1s As Byte ' zmienna czasu
- $include "Config_PCF8583.bas"
- Config Serialin0 = Buffered , Size = 25 ' Buforowanie uart (UART odbierany w przerwaniu - rozmiar 25 znaków)
- $include "Config_DS18B20.bas"
- Config 1wire = PortD.6 ' Konfiguracja 1-WIRE
- $include "Config_Volt.bas"
- ' Zmienne uart
- Dim Bufor As Byte
- Dim T_str As String * 25
- Dim T As String * 1
- Dim Ilosc_liter As Byte
- Dim Wartosc As word
- Dim Wartosc_t As String * 25
- ' zmienna sterująca diodą led
- Dim L As Byte
- Dim Stare_l As Byte
- ' Zmienne zapisujące datę przeglądu technicznego do eeprom
- Dim N As Byte
- Dim Q As Byte
- Dim Q_str As String * 25
- Dim Buff(20) As Byte At Q_str Overlay
- ' Zmienne zapisujące datę wymiany oleju do EEPROM
- Dim A As Byte
- Dim A_str As String * 25
- Dim I As Byte
- Dim I_str As String * 25
- ' zmienna inicjująca wysłanie danych przez bluetooth
- Dim C As Byte ' wysłanie daty przeglądu
- Dim B As Byte ' wysłanie daty wymiany oleju
- Dim K As Byte ' wysłanie daty ubezpieczenia
- Deflcdchar 1,6,21,13,6,6,13,21,6 'Bluetooth
- ' Konfiguracja portu usypiania
- Config Portd.7 = Input : Portd.7 = 1 : Motor Alias Pind.7 ' silnik włączony = 0 / wyłączony = 1
- ' Konfiguracja portów dla klawiatury
- Config Portd.2 = Input : Portd.2 = 1 : F1 Alias Pind.2
- ' Konfiguracja opóźnienia włączenia podświetlenia LCD
- Config Portd.4 = Input : Portd.4 = 1 : Int_pcf Alias Pind.4 ' Wejście sygnału z Pinu INT PCF8583
- Dim Lock As Byte ' Zmienna pomocnicza (flaga) do odliczenia 5 sekund
- Dim Licznik As Byte
- Dim Jest_5_impulsow As Byte
- ' Konfiguracja zmiennych dla Menu Screen
- Dim Menu As Byte
- Dim Refresh As Byte
- ' Konfiguracja portu LED kontrolka gołoledzi
- Config Portd.5 = Output : Portd.5 = 1 : Led_glaze Alias Portd.5 ' kontrolka gołoledzi
- 'sub zapisuje Eeprom wartością pod podanym adresem
- Sub Write_eeprom(byval Adres As Byte , Byval Value As Byte)
- I2cstart
- I2cwbyte Addressw
- I2cwbyte Adres
- I2cwbyte Value
- I2cstop
- Waitms 10
- End Sub
- 'funkcja zwraca wartosć bajtu pod podanym adresem w eepromie
- Function Read_eeprom(byval Adres As Byte ) As Byte
- I2cstart
- I2cwbyte Addressw
- I2cwbyte Adres
- I2cstart
- I2cwbyte Addressr
- I2crbyte Read_eeprom , Nack
- I2cstop
- End Function
- L = Read_eeprom(2) 'odczyt L spod miejsca 2
- clear serialin0
- ' ==============GŁÓWNA PĘTLA=================
- Do
- Q_str = T_str
- 'A_str = T_str
- ' I_str = T_str
- If L = 1 Then Led = 0 ' LED WYŁĄCZONA
- If L = 2 Then Led = 1 ' LED WŁĄCZONA
- If C = 1 Then Gosub Wyslij
- If Q > 0 Then Gosub Zapisz
- If A > 0 Then Gosub Zapisz_oil
- If B = 1 Then Gosub Wyslij_oil
- If I > 0 Then Gosub Zapisz_ubezp
- If K = 1 Then Gosub Wyslij_ubezp
- If Refresh = 1 Then 'odswiezanie co sekunde albo na żądanie
- Refresh = 0
- End If
- Select Case Menu
- Case 0
- '==========GŁÓWNY EKRAN Z GODZINĄ I DATĄ==============
- Blad = Pcf8583_gettime() ' odczytaj godzinę i date z układu PCF8583 , funkcja zwraca kod błędu
- If Blad = 2 Then ' jeżeli uszkodzona data
- Locate 1 , 1 : Lcd " SET CLOCK " ' wyświetl komunikat
- Locate 2 , 1 : Lcd Spc(20)
- Elseif Blad = 1 Then ' jeżeli błąd magistrali I2C
- Locate 1 , 1 : Lcd " E R R O R " ' wyświetl komunikat
- Lcd Spc(11)
- Locate 2 , 1 : Lcd " B U S I2C "
- Elseif Blad = 0 Then ' jeżeli prawidłowo odczytane dane
- Call Displaytime() ' wyświetl zegar
- End If
- Case 1
- '=========EKRAN Z TEMPERATURĄ IN/OUT=================
- Call Displaytemp()
- Case 2
- '=========EKRAN Z POMIAREM NAPIĘCIA POKŁADOWEGO==============
- Call Displayvolt()
- End Select
- Debounce F1 , 0 , Menu_sub , Sub ' Każde naciśnięcie przycisku F1 powoduje przejscie do kolejnego ekranu
- If Motor = 1 then : Waitms 5 : Bitwait Motor , Set : Gosub Uspij ' Jeśłi silnik wyłączony, to idź do procedury Usypiania
- end if
- Call Display_led_glaze() ' Sterowanie kontrolką gołoledzi
- 'co sekunde
- If 1s = 1 Then ' jesli uplynela sekunda (te flage ustawia Timer)
- 1s = 0 ' skasuj flage by w petli dokonywalo sie to tylko raz na 1s
- End If
- Bufor = Ischarwaiting()
- If Bufor = 1 Then Gosub Odczytaj_uart ' Jeśli w buforze pojawią się dane z uart,to idź do procedury odbioru danych
- Loop
- End
- ' ===============KONIEC GŁÓWNEJ PĘTLI=========================
- $include "PCF8583.bas"
- $include "DS18B20.bas"
- $include "Volt.bas"
- 'odmierzanie czasu
- Przerwanie:
- 1s = 1
- Return
- ' Przewijanie ekranów
- Menu_sub:
- Incr Menu
- If Menu > 2 Then Menu = 0
- Cls : Refresh = 1
- Return
- ' Procedura odbioru danych z UART
- Odczytaj_uart:
- T_str = "" 'usuniecie tego co jest
- Do
- Bufor = Waitkey()
- Locate 1 , 10 : Lcd Bufor ' nowa linijka
- If Bufor = 13 Then Exit Do 'jak enter to wyjdź
- If Bufor = 10 Then Exit Do ' nowa linia
- If Refresh = 1 Then Exit Do
- T_str = T_str + Chr(bufor)
- Loop
- Locate 1 , 10 : Lcd Bufor ' nowa linijka
- Ilosc_liter = Len(t_str)
- T = Mid(t_str , 1 , 1)
- Delchar T_str , 1
- Wartosc = Val(t_str)
- Select Case T
- ' Zegarek
- Case "M"
- Minute = Wartosc
- Case "H"
- Hour = Wartosc
- Case "S"
- Second = Wartosc
- ' dioda
- Case "L"
- L = Wartosc
- ' kalendarz
- Case "Z"
- Day = Wartosc
- Case "W"
- Month = Wartosc
- Case "Y"
- Year = Wartosc
- ' zapis danych
- Case "Q" ' zmienna zapisu daty przeglądu technicznego
- Q = Wartosc
- Case "C" ' zmienna wysłania daty przeglądu technicznego
- C = Wartosc
- Case "A" ' zmienna zapisu daty wymiany oleju silnikowego
- A = Wartosc
- Case "B" ' zmienna wysłania daty wymiany oleju silnikowego
- B = Wartosc
- Case "I" ' zmienna zapisu daty kolejnego ubezpieczenia
- I = Wartosc
- Case "K" ' zmienna wysłania daty kolejnego ubezpieczenia
- K = Wartosc
- Cls
- End Select
- Blad = Pcf8583_storetime(second , Minute , Hour , Day , Month , Year)
- ' ========================Zapis warotści zmiennej LED do 24C02===========================================
- If Stare_l <> L Then
- Stare_l = L
- Call Write_eeprom(2 , L)
- end if
- ' ========================Zapis daty przeglądu technicznego do 24C02=====================================
- Zapisz:
- Do
- If Q > 0 then
- Q_str = T_str
- For N = 1 To 20
- Call Write_eeprom(n + 5 , Buff(n)) 'przekazując można robić obliczenia
- Next
- end if
- Q = 0
- Return
- Loop
- ' ========================Odczyt daty przeglądu techniczengo i wysłanie danych do smartfona================
- Wyslij:
- Do
- For N = 1 To 20
- Buff(n) = Read_eeprom(n + 5)
- Next
- Print Q_str
- C = 0
- return
- loop
- ' ========================Zapis daty wymiany oleju silnikowego do 24C02===================================
- Zapisz_oil:
- Do
- If A > 0 Then
- A_str = T_str
- For N = 1 To 20
- Call Write_eeprom(n + 26 , Buff(n))
- Next
- end if
- A = 0
- Return
- Loop
- ' =====================Odczyt daty wymiany oleju silnikowego i wysłanie danych do smartfona===============
- Wyslij_oil:
- Do
- For N = 1 To 20
- Buff(n) = Read_eeprom(n + 26)
- Next
- Print A_str
- B = 0
- Return
- loop
- ' ========================Zapis daty ubezpieczenia do 24C02===================================
- Zapisz_ubezp:
- Do
- If I > 0 Then
- I_str = T_str
- For N = 1 To 20
- Call Write_eeprom(n + 55 , Buff(n))
- Next
- end if
- I = 0
- Return
- Loop
- ' =====================Odczyt daty ubezpieczenia i wysłanie danych do smartfona===============
- Wyslij_ubezp:
- Do
- For N = 1 To 20
- Buff(n) = Read_eeprom(n + 55)
- Next
- Print I_str
- K = 0
- Return
- loop
- ' ======================Procedura stanu uśpienia gdy silnik wyłączony=====================================
- Uspij:
- Cls
- Motor = 1
- Do
- Led_glaze = INT_PCF
- If Motor = 1 then Display off : Podswietlenie = 0 ' Jeśli silnik wyłączony, to wyłącz LCD i podświetlenie
- 'Led_glaze = 1 ' Kontrolka gołoledzi wyłączona
- 'end if
- If Motor = 0 then ' Jeśli silnik włączony, to:
- ' ########################## Odpowiada za opóźnienie 5 sekund włączenia LCD ############################
- If Int_pcf = 0 Then 'jeśli PCF ustalił stan niski
- Lock = 1 'to zapamietaj, ustaw flage
- Else 'jesli PCF ustawil już stan wysoki
- If Lock = 1 Then 'a byl wczesniej stan niski (flaga)
- Lock = 0 'skasuj flage do czasu kolejnego niskiego stanu
- Incr Licznik 'tylko raz na zmiane stanu zwiekszamy licznik
- If Licznik = 5 Then ' jeśli licznik osiągnął wartość 5 (5sekund), to
- Licznik = 0 ' zeruj licznik
- Jest_5_impulsow = 1 'przejdź do włączenia podświetlenia
- End If
- End If
- End If
- If Jest_5_impulsow = 1 Then
- Jest_5_impulsow = 0
- ' ######################## Koniec części opóźniającej włączenie LCD ###################################
- Podswietlenie = 1 ' włącz podświetlenie
- Display on ' włącz wyswietlacz
- cls ' wyczyść wyswietlacz
- ' Wyczyść informacje zgromadzone w Buforze UART
- return ' wracaj do głównego programu
- end if
- end if
- 'end if
- Loop