[Bascom] Zapis i odczyt zmiennych do zewnętrznego eepromu.

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

[Bascom] Zapis i odczyt zmiennych do zewnętrznego eepromu.

Post autor: matrix » 05 kwie 2013, 22:14

Da się w bascomie zapisać do zewnętrznej pamięci eeprom wiele zmiennych o różnej wielkości?

Powiedzmy że mam zmienne typu bit, byte, word i single. Da się to jakoś w ładny sposób zapisywać i odczytywać z eepromu?

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 06 kwie 2013, 8:45

Zmiennych zasadniczo nie zapisuje się w pamięci EEPROM, chyba że zastąpisz ją pamięcią MRAM (Magnetic RAM, czyli nieulotny RAM nawet po wyłączeniu zasilania).
Czy da się to ładnie zapisywać i odczytywać tak, ale czas dostępu do tych danych będzie długi, i będziesz musiał używać czegoś na wzór wskaźników, aby to obsługiwać.
Wskaźniki powinny być 16-bitowe, czyli typu WORD.
Taki wskaźnik nie będzie niczym innym jak adresem takiej zmiennej w pamięci, przy czym istotna będzie organizacja danych w takiej pamięci. Pierwsza strona czyli 64 bajtów, powinna być zarezerwowana dla zmiennych typu BIT. Dla czego ? Otóż uniwersalny mechanizm obsługi takiej zewnętrznej pamięci będzie wymagał pewnej sztuczki. Otóż wspomniany 16-bitowy wskaźnik będzie adresem zmiennej, oraz jej typikator, tak to się chyba zwało.
I tak dwa ostatnie bity tego wskaźnika to typikator, określający typ odczytywanej zmiennej, i tak.
00 - BIT w tym przypadku, pierwszy bajt 16-bitowego wskaźnika to maska do wyłuskania konkretnego bitu z bajtu danych w EEPROM, drugi bajt wskaźnika to 6 bitowy adres bajtu z którego ma zostać wyłuskany stan bitu. Daje to 64bajty x 8 bit czyli mozliwość zapisania do 512 zmiennych bitowych w pamięci.
01 - bajt, młodsze 14 bitów wskaźnika - 64 wskazuje adres bajtu w EEPROM
10 - słowo (WORD lub INT), adres jak wyżej.
11 - podwójne słowo (SINGLE) adres jak wyżej.
Oczywiście obsługa tego wymaga napisania odpowiednich procedur i funkcji, oraz podzielenia pamięci, na strony, i/lub rozdziały, kolejno dla danych BIT, BYTE, WORD-INT, Single.
Ogólnie powstanie coś na wzór mini dysku twardego mającego stały podział logiczny, na pewne sektory przydzielone dla konkretnego typu danych.
Ostatnio zmieniony 06 kwie 2013, 9:04 przez kayron, łącznie zmieniany 4 razy.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 06 kwie 2013, 8:55

Czas dostępu nie ma znaczenia. Chodzi o to że jeśli ja wybiorę z menu zapis to ma zapisać te dane do nieulotnej pamięci, a po wyłączeniu i włączeniu zasilania program ma odczytać zapisane wcześniej dane. Dalej będzie korzystał z tych danych w zmiennych lokalnych/globalnych.

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 06 kwie 2013, 9:11

A jaką konkretnie kostkę EEPROM byś chciał używać, i jaki mieć sposób dostępu do danych, w sensie wywołania zunifikowanej nazwy zmiennej, czy np. podawania, adresu ?
Zunifikowana nazwa to coś takiego np. B6_12 - odczytaj/zapis bit6 z zmiennej 12.
nazwa B12 -to będzie już odczytaj bajt nr 12, itd.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 06 kwie 2013, 9:29

Za pamięcią jeszcze się nie rozglądałem, ale sądzę że coś ala 24CXX.
Co do zapisu zmiennych to chciałbym zapisywać i odczytywać to bezpośrednio z nazwy zmiennej.

Czyli mam zmienną o nazwie lampka i tak chciałbym to zapisywać. Przyznam że jeszcze nie korzystałem z zapisu do zewnętrznego eepromu i jestem w tym dość mocno zielony.
Przy zapisie i odczycie najzwyczajniej nie chcę się zastanawiać co zapisać i co odczytać? Chę tylko włączyć zapis i przy "wstawaniu" programu włączyć odczyt. To wszystko. Całość ma mi się właściwie zapisać i właściwie odczytać przy czym zapisywanie i odczyt nie będą wybiórcze czyli pojedyncze zmienne a wszystkie na raz.

Może powinienem zapisać to do jakiejś zmiennej tablicowej i zapisać całą tablicę?

Pytanie pomocnicze:
mogę wrzucić na jedną szynę I2C eeprom i rtc?

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 06 kwie 2013, 9:55

Mi bardziej chodziło o pojemność tej pamięci EEPROM. Jeżeli przyjąć ,że 64 bajty pójdą na zmienne BIT, 64 na Byte, to na WORD i INT pójdzie już 128 bajtów, a na SINGLE 256B. Łącznie daje to minimum 512B EEPROM, praktycznie trzeba by zastosować przynajmniej 2KB kość. czyli jak mnie pamięć nie myli 24C16.
Samo posługiwanie się nazwami, może być trochę kłopotliwe, ponieważ zadeklarowana zmienna jest przypisywana do pamięci RAM, użycie jej nazwy będzie trudne, w odnośniku do innej pamięci, a wynika to z tego że Baskom nie obsługuje wskaźników. Ale to jest kwestia pogłówkowania. Pewnym rozwiązaniem może być mechanizm MMU, czyli tablicowanie adresów.
Co do drugiego pytania. TAK możesz na jednej szynie I²C mieć RTC i EEPROM, będą miały po prostu inny adres wywołania, zresztą chyba i tak mają fabrycznie.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 06 kwie 2013, 10:13

kayron pisze:(...)Samo posługiwanie się nazwami, może być trochę kłopotliwe, ponieważ zadeklarowana zmienna jest przypisywana do pamięci RAM, użycie jej nazwy będzie trudne, w odnośniku do innej pamięci, a wynika to z tego że Baskom nie obsługuje wskaźników.(...)
Z tym nie ma jakiegoś tam kłopotu. Ogólnie wiem że nie można tych samych nazw co zmienne wpisywać do eepromu bo się najzwyczajniej nie da. Próbowałem tak z eepromem wewnętrznym.
Chodzi tylko o to by te same dane zapisane ze zmiennych trafiły w te same zmienne po odczycie.
kayron pisze: Co do drugiego pytania. TAK możesz na jednej szynie I²C mieć RTC i EEPROM, będą miały po prostu inny adres wywołania, zresztą chyba i tak mają fabrycznie.
Tu pytałem tak dla pewności. Wiem o adresowaniu zarówno rtc jak i o adresowaniu eeprom. Ale czytałem też na necie że są kłopoty.

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 06 kwie 2013, 11:58

Ciężka sprawa jednak to pogodzić, bo BASCOM to nie C. Sposób pewnie jest, ale będzie upierdliwy w stosowaniu.
Chyba bez naskrobania wstawki Asemblerowej nie da się tu nic zdziałać, bo baskom nie ma polecenie MEM znanego mi z Turbo Pascala, które pozwalało bezpośrednio odwoływać się do RAMu, a ponieważ nie ma w BASCOM wskaźników, to nie mogę używać nazwy zmiennej, jako adresu. Łącząć pewną sztuczkę z deklarowaniem zmiennych, z określony adresem w RAM, wstawkę asemblerowa która stworzy instrukcję MEM w BASCOM, da sie pewnie to zrobić, ale i tak to będzie taki wskaźnikopodobny przeszczep mechanizmów z C.
Ostatnio zmieniony 06 kwie 2013, 12:15 przez kayron, łącznie zmieniany 1 raz.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 06 kwie 2013, 12:15

Na razie nie mam zewnętrznej pamięci więc nawet nie mam jak testować.

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 06 kwie 2013, 12:17

Ale możesz używać wewnętrznego EEPROM jak masz wolny, można w nim deklarować zmienne.
Jaki procesor masz, bo to też ma znaczenie.
Dla wenętrznego EEPROMu jest to bardzo proste, bo masz instrukcje ReadEEPROM i WriteEEPROM. Jedyne co sobie musisz zestandaryzować to adresy, a to zrobisz CONSTem.
np.

Kod: Zaznacz cały

Const wsk_licznik =&h01

dim licznik as byte

'zapis to
WriteEEPROM licznik, wsk_licznik
'odczyt to
ReadEEPROM licznik, wsk_licznik
Cała filozofia. Podobnie bedzie to działać na EEPROM zewnętrznym, ale będziesz miał funkcje lub procedurę I2C.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 06 kwie 2013, 13:11

Do dyspozycji jest procesor atmega32.
Może i masz rację. "Przestraszyłem" się że wewnętrzny eeprom ma limit zapisu do 10 tys cykli. ale właśnie sobie uzmysłowiłem że tyle razy te wartości nie będą zapisywane.

Jednak co dwie głowy to nie jedna. Na wszelki wypadek, do testów zakupiłem sobie właśnie dwie pamięci, AT24c16 i AT24c64.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 06 kwie 2013, 14:16

Jest gitarowo, no lepiej już chyba być nie może.
Deklaruję sobie zmienną globalną i zmienną eeprom:

Kod: Zaznacz cały

dim zmienna as byte                'zwykła zmienna
dim zmienna_eprom as eram byte    ' zmienna eeprom
jeśli potrzebuję to zapisuję to do pamięci w ten sposób:

Kod: Zaznacz cały

writeeeprom zmienna, zmienna_eprom
a jeśli potrzebuję to odczytać to walę:

Kod: Zaznacz cały

readeeprom zmienna, zmienna_eprom
i mam po kłopocie. Normalnie bosko.

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 06 kwie 2013, 15:03

Twój sposób jest trochę błędny, ponieważ zmienną adresujesz zmienną, czyli co tak naprawdę wskazujesz ? ODP. przypadkową wartość w EEPROM. Dodatkowo bardzo łatwo w takiej metodzie zaadresować obszar EEPROM, poza dostępną przestrzenią pamięci, i wtedy dostaniesz buraki jako argument.
Mój sposób jest prawidłowy, zmienna i wskaźnik w postaci CONSTa, z adresem kopi w EEPROM. Ma to dwie zalety.
1. zawsze masz wskazany prawidłowy adres kopi, bo to stała w programie, a nie zmienna.
2. Jakakolwiek zmiana adresu kopi w całym programie to tylko zmiana w deklaracji CONSTa, na inny nowy adres np. w przypadku uszkodzenia danej komórki EEPROM.

Przy czym używając EEPROMa (tego w procu też) pamiętaj aby nie używać komórki o adresie 0, nie jest to zalecane przez ATMELa, ponieważ gdyby wystąpiły zakłócenia zasilania, istnieje ryzyko że zostanie tam zapisana przypadkowa wartość.
No i żadnym z rozważanych sposobów nie zapiszesz w prosty sposób zmiennej typu BIT. Zresztą chyba nawet BASCOM nakłada jakieś ograniczenia na ich używanie.

Uwaga! Zmienne bitowe mogą być umieszczone tylko w pamięci SRAM (wewnętrznej). Help BASCOMa

PS. w twoim sposobie wystarczy zwykłe przypisanie, jak się nie mylę, tzn.
Odczyt z EEPROM
Zmienna = zmienna_eeprom
Zapis do EEPROM
Zmienna_eeprom = zmienna
Nie trzeba chyba korzystać z funkcji Read i write EEPROM, ale mogę sie mylić ?
Ostatnio zmieniony 06 kwie 2013, 15:20 przez kayron, łącznie zmieniany 1 raz.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 06 kwie 2013, 15:20

kayron pisze:Twój sposób jest trochę błędny, ponieważ zmienną adresujesz zmienną, czyli co tak naprawdę wskazujesz ?
Nie wiem czy jest on taki do końca błędny. Pisząc:
dim zmienna_eprom as eram byte
wrzucam ją do pamięci eeprom procka a ten sam mi ją adresuje.

Z adresowaniem zerowym to wiem, natomiast jeśli chodzi o adresowanie ogólne działa jak chciałem. Nie muszę się martwić czy zmienna dioda jest pod adresem 01 a zmienna lampa pod adresem 02. Nie martwię się że błędnie wpiszę je na przykład odwrotnie nie wspominając o fakcie że w tej chwili mam zmiennych około 20 sztuk.

Bascom sam adresuje mi komórki. A żeby wyeliminować możliwość że zaadresuje mi którąś pod adresem 00 to nadpiszę ten adres jakąś w ogóle niepotrzebną mi zmienną w ten sposób:

dim niepotrzebna_zmienna as eram byte at &h00

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 06 kwie 2013, 15:28

Bascom sam adresuje mi komórki.
Nie nie adresuje ci sam. On ci skompiluje taki zapis, jak podałeś, ale adresować ci będzie przypadkowe komórki EEPROM,
Taki zapis:
WriteEEPROM zmienna, zmienna_eeprom oznacza
Zapisz wartość zmiennej z RAMu do komórki EEPROM wskazanej przez wartość Zmiennej_EEPROM, czyli domyślnie z komórki EEPROM przypisanej do Zmienna_eeprom, w której fabrycznie jest wartość FF (255), oczywiście jeżeli wcześniej nie zrobisz np. operacji zmienna_eeprom = 1. Czyli będziesz miał zapis pod adres 255.
Nie sugeruj się tym że kompilator ci coś skompiluje bez errorów, zrób sobie symulację, z printem który ci wyświetli na terminali odczytywane i zapisywane tą metodą dane.
PS. postaram sie napisać symulacje w BASCOM i ci ją tu wkleję.

ODPOWIEDZ