Obsługa pamięci szeregowych EEPROM i DataFlash w Bascom, część 1

Obsługa pamięci szeregowych EEPROM i DataFlash w Bascom, część 1
Pobierz PDF Download icon

W wielu systemach cyfrowych, które mają zbierać dane z zewnątrz, powinny być one zapisywane w pamięci nieulotnej o właściwie dobranej pojemności. Pamięci nieulotne są także wykorzystywane do zapamiętywania ustawianych parametrów systemu. W tego rodzaju zastosowaniach ich pojemność może być niewielka – zazwyczaj do 1 kB. Wiele mikrokontrolerów ma wbudowaną pamięć nieulotną, której zazwyczaj niewielka pojemność umożliwia tylko zapamiętanie konfiguracji urządzenia. W przypadku mikrokontrolerów bez wewnętrznej pamięci EEPROM można bez problemu dołączyć pamięć zewnętrzną. Do tego celu nadają się pamięci szeregowe, gdyż do ich dołączenia zazwyczaj nie jest potrzebnych wiele linii mikrokontrolera.

W przypadku małej liczby danych do zapamiętania (danych konfiguracyjnych itp.) można więc stosować pamięci nieulotne EEPROM o niewielkiej pojemności, zazwyczaj od kilkunastu bajtów do kilkudziesięciu kilobajtów. W przypadku, gdy będzie trzeba zapamiętać dużą liczbę danych, np. z pomiarów, to odpowiednie będą szeregowe pamięci DataFlash, których pojemność może wynosić do kilku megabajtów. W artykule zostanie przedstawiona obsługa pamięci EEPROM oraz DataFlash z poziomu Bascoma. Zostaną przedstawione pamięci z najpopularniejszymi interfejsami I2C oraz SPI, jak: AT24C02 (pojemność 256 bajtów), AT24C16 (pojemność 2 kB), AT24C64 (pojemność 8 kB), AT93C64 (pojemność 128 bajtów) oraz DataFlash AT45DB011 o pojemności ponad 135 kB.

Pamięci szeregowe EEPROM z rodziny AT24Cxx

Pamięci z rodziny AT24Cxx mają interfejs I2C, a więc do komunikacji z nimi wykorzystywane są tylko dwie linie mikrokontrolera.

W tab. 1 przedstawiono parametry kilku typów pamięci AT24Cxx. Pamięcią, którą można wykorzystać do zapamiętywania parametrów konfiguracyjnych, jest AT24C02 o pojemności 256 bajtów.

Rys. 1. Schemat blokowy pamięci typu AT24C02 

Schemat blokowy pamięci tego typu przedstawiono na rys. 1. Linie adresowe A2...A0 są liniami wyboru jednej z ośmiu pamięci jakie mogą być dołączone do magistrali I2C (np. dla AT24C02). Zwarcie linii WP do plusa zasilania blokuje zapis do pamięci.

Rys. 2. Schemat dołączenia pamięci EEPROM do mikrokontrolera

Na rys. 2 przedstawiono schemat podłączenia pamięci do układu uruchomieniowego z mikrokontrolerem ATMEGA8 w którym będzie testowana obsługa pamięci EEPROM. Płytka jest połączona z komputerem za pomocą łącza RS232. Dane będą przesyłane tym interfejsem i zapisywane do pamięci oraz z niej odczytywane. mikrokontrolera. Układ U2 jest konwerterem napięć do poziomów zgodnych z normą RS232. Rezystory R1, R2 są rezystorami podciągającymi dla linii sygnałowych magistrali I2C.

Listing 1. 'Program komunikujący się z pamięcia 24C02 (2k - 256*8) - pojemność 256 bajtów 'Komunikacja z pamiecia odbywa sie przy pomocy magistrali I2C 'Mikrokontroler ATMEGA8 taktowany czestotliwoscia 8MHz 'W programie do pamieci (komorki 0...255) wpisywane sa wartosci liczbowe od 0 do 255, 'nastepnie dane zapisane do pamieci sa odczytywane i weryfikowane pod wzgledem poprawnosci zapisu 'zarowno wartosci danych zapisywanych jak i odczytywanych sa wysylane do terminala poprzez interfejs RS232. 'Predkosc komunikacji przez RS232 wynosi 9600 bodow. 'W przypadku bledu zapisu do pamieci wysylany jest do terminala stosowny komunikat 'Marcin Wiązania 'marcin.wiazania@ep.com.pl $regfile = "m8def.dat" 'informuje kompilator o pliku dyrektyw mikrokontrolera $crystal = 8000000 'informuje kompilator o częstotliwości oscylatora taktujacego mikrokontroler $baud = 9600 'informuje o predkosci transmisji interfejsu RS232 Const Adr_w = 160 'adres zapisu danej do pamieci EEPROM Const Adr_r = 161 'adres odczytu danej do pamieci EEPROM Config Sda = Portc.4 'konfiguracja linii SDA interfejsu I2C Config Scl = Portc.3 'konfiguracja linii SCL interfejsu I2C Config I2cdelay = 5 'konfiguracja opoznienia (czestotliwosci) linii zegarowej SCL Declare Sub Zap_eeprom(byval Adres As Byte , Byval Dana As Byte) 'procedura zapisu danej do pamieci Declare Sub Odc_eeprom(byval Adres As Byte , Dana As Byte) 'procedura odczytu danej z pamieci Dim Adres As Byte 'zmienna adresu komorki pamieci Dim Dana As Byte 'zmienna zmienna na odczytana lub zapisana dana do pamieci Dim I As Byte 'zmienna licznikowa Print "Zapis" 'wyslanie do terminala tekstu For I = 0 To 255 'petla wykonywana dla I=0 do I=255 Call Zap_eeprom(i , I) 'zapis do EEPROM wartosci zmiennej I pod adres wskazywany przez I Print Hex(i) ; " "; 'wyslanie do terminala wartosci zapisywanej do EEPROM w postaci szesnastkowej Next I 'zwiekszenie o 1 wartosci I Print 'wyslanie do terminala wiersza odstepu Print "Odczyt i weryfikacja" 'wyslanie do terminala tekstu For I = 0 To 255 'petla wykonywana dla I=0 do I=255 Call Odc_eeprom(i , Dana) 'odczytanie z EEPROM wartosc z komorki o adresie wskazywanym przez I If Dana = I Then '--weryfikacja danych-- jesli Dana = I to Print Hex(dana) ; " "; 'wyslanie do terminala odczytanej wartosci z pamieci w postaci szesnastkowej Else 'w przeciwnym razie Print "Dane nieprawidlowe" 'wyslanie do terminala tekstu Exit For 'opuszczenie petli For End If Next I 'zwiekszenie o 1 wartosci I End 'koniec programu Sub Zap_eeprom(byval Adres As Byte , Byval Dana As Byte) 'procedura zapisu danej do EEPROM I2cstart 'start transmisji I2cwbyte Adr_w 'zapis adresu ukladu pamieci do zapisu I2cwbyte Adres 'adres komorki pamieci I2cwbyte Dana 'zapis danej I2cstop 'koniec transmisji Waitms 10 'opoznienie 10 ms End Sub 'koniec procedury Sub Odc_eeprom(byval Adres As Byte , Dana As Byte) 'procedura odczytu danej do EEPROM I2cstart 'start transmisji I2cwbyte Adr_w 'zapis adresu ukladu pamieci do zapisu I2cwbyte Adres 'adres komorki pamieci I2cstart 'ponowny start transmisji I2cwbyte Adr_r 'zapis adresu ukladu pamieci do odczytu I2crbyte Dana , Nack 'odczyt bajta danej - bez potwierdzenia sygnałem ACK I2cstop 'koniec transmisji End Sub 'koniec procedury

Na list. 1 przedstawiono przykład programu obsługującego pamięć AT24C02. Do komórek pamięci wpisywane są w programie kolejno wartości od 0 do 255. Zapis do pamięci EEPROM następuje w procedurze Zap_eeprom, która ma dwa parametry. Pierwszym jest adres a drugim wartość danej do zapisania. Po zainicjowaniu magistrali I2C sygnałem startu jest wysyłany adres wybieranej pamięci, którego format przedstawiono na rys. 3.

Rys. 3. Format słowa adresu pamięci AT24C02

Bity A2...A0 odpowiadają stanom zewnętrznych linii A2...A0 pamięci. Bit R/W wskazuje czy będzie następował odczyt z pamięci, czy zapis do pamięci. Ponieważ linie A2...A0 pamięci zostały zwarte do masy, adres zapisu do pamięci będzie wynosił 160, a odczytu z niej 161.

Rys. 4. Ramka zapisu jednej komórki pamięci

Na rys. 4 przedstawiono ramkę z sygnałami podczas zapisu jednego bajtu pamięci. Każda ramka kończy się sygnałem potwierdzenia (ACK) wysyłanym przez pamięć, po czym wysyłany jest adres bajtu (słowa) pamięci. Ponieważ pamięć ma pojemność 256 bajtów, adres jest 8–bitowy. Po otrzymaniu potwierdzenia wysyłana jest dana do zapisania w zaadresowanym bajcie (słowie). W procedurze zapisu do pamięci występuje opóźnienie (zależne od typu pamięci i producenta), które jest wymagane ze względu na czas zapisu. Do odczytu danych z pamięci służy procedura Odc_eeprom mająca także dwa parametry: adres oraz wartość odczytanej komórki.

Rys. 5. Ramka odczytu pamięci

Ramka z sygnałami przy odczycie z pamięci przedstawiono na rys. 5. W pierwszej kolejności wysyłany jest (po sekwencji startu) adres pamięci do zapisu, czyli 160, a następnie adres słowa pamięci, z którego ma nastąpić odczyt. Po kolejnej sekwencji startu wysyłany jest adres pamięci do odczytu, po którym następuje odczyt danej z zaadresowanego słowa, już bez bitu potwierdzenia. Po każdej zakończonej komunikacji z pamięcią następuje wysłanie sygnału stopu. W pętli głównej programu do każdego słowa pamięci jest zapisywana jakaś liczba, która jest także wysyłana do terminala. Po zapisaniu wszystkich bajtów, następuje odczyt oraz weryfikacja zawartości każdego z nich. Odczytane wartości z pamięci są wysłanie do terminala. W przypadku wykrycia błędu zapisu, do terminala zostanie wysłany odpowiedni komunikat.

Rys. 6. Widok okna terminala po zakończeniu działania programu demonstracyjnego

Na rys. 6 przedstawiono widok okna terminala po zakończeniu programu.
Komunikacja z pamięciami AT24Cxx o większych pojemnościach jest trochę trudniejsza. Przykładowo, pamięć AT24C16, która ma pojemność 2 kB nie ma zewnętrznych linii wyboru adresu, co oznacza, że do magistrali I2C może być dołączona tylko jedna pamięć. Bitowe odpowiedniki adresu pamięci zostały zastąpione adresami stron, z których każda ma 256 bajtów pamięci, czyli pamięć AT24C16 ma 8 stron.

Rys. 7. Format słowa adresu pamięci AT24C16

Na rys. 7 przedstawiono format słowa adresu pamięci AT24C16. Bity P2...P0 określają właśnie adres strony. Budowa tej pamięci oraz sposób jej podłączenia do mikrokontrolera jest identyczny jak przedstawiono na rys. 1 oraz rys. 2.

Listing 2. 'Program komunikujący się z pamięcia 24C16 (16k - 2048*8) - pojemność 2048 bajtów 'Komunikacja z pamiecia odbywa sie przy pomocy magistrali I2C 'Mikrokontroler ATMEGA8 taktowany z czestotliwoscia 8MHz 'Pamiec posiada 8 stron z ktorych kazda ma 256 komorek co daje pojemność 2kB (2048 komorek) 'W programie do pamieci (komorki 0...2048) wpisywane sa wartosci liczbowe numerow stron do których nastepuje zapis. 'Nastepnie dane zapisane do pamieci sa odczytywane i weryfikowane pod wzgledem poprawnosci zapisu 'Zarowno wartosci danych zapisywanych jak i odczytywanych sa wysylane do terminala poprzez interfejs RS232. 'Predkosc komunikacji przez RS232 wynosi 9600 bodow. 'W przypadku bledu zapisu do pamieci wysylany jest do terminala stosowny komunikat 'Marcin Wiązania 'marcin.wiazania@ep.com.pl $regfile = "m8def.dat" 'informuje kompilator o pliku dyrektyw mikrokontrolera $crystal = 8000000 'informuje kompilator o częstotliwości oscylatora taktujacego mikrokontroler $baud = 9600 'informuje o predkosci transmisji interfejsu RS232 Const Adr_w = 160 'adres zapisu danej do pamieci EEPROM Const Adr_r = 161 'adres odczytu danej do pamieci EEPROM Config Sda = Portc.4 'konfiguracja linii SDA interfejsu I2C Config Scl = Portc.3 'konfiguracja linii SCL interfejsu I2C Config I2cdelay = 5 'konfiguracja opoznienia (czestotliwosci) linii zegarowej SCL Declare Sub Zap_eeprom(byval Adres As Word , Byval Dana As Byte) 'procedura zapisu danej do pamieci Declare Sub Odc_eeprom(byval Adres As Word , Dana As Byte) 'procedura odczytu danej z pamieci Dim Adres As Word 'zmienna adresu komorki pamieci Dim Dana As Byte 'zmienna zmienna na odczytana lub zapisana dana do pamieci Dim I As Word 'zmienna licznikowa Dim Temp As Byte 'zmienna pomocnicza Dim Zm_pom As Word 'zmienna pomocnicza do przeliczenia adresu Print "Zapis" 'wyslanie do terminala tekstu For I = 0 To 2047 'petla wykonywana dla I=0 do I=2047 Zm_pom = I / 256 'obliczenie numeru strony pamieci Dana = Zm_pom 'zapis numeru strony do zmiennej dana Call Zap_eeprom(i , Dana) 'zapis do EEPROM wartosci zmiennej dana pod adres wskazywany przez I Print Hex(dana) ; " "; 'wyslanie do terminala wartosci zapisywanej do EEPROM w postaci szesnastkowej Next I 'zwiekszenie o 1 wartosci I Print 'wyslanie do terminala wiersza odstepu Print "Odczyt i weryfikacja" 'wyslanie do terminala tekstu For I = 0 To 2047 'petla wykonywana dla I=0 do I=2047 Call Odc_eeprom(i , Dana) 'odczytanie z EEPROM wartosc z komorki o adresie wskazywanym przez I Zm_pom = I / 256 'obliczenie odczytywanej strony pamieci If Dana = Zm_pom Then '--weryfikacja danych-- jesli Dana = zm_pom - czyli numerowi strony to Print Hex(dana) ; " "; 'wyslanie do terminala odczytanej wartosci z pamieci w postaci szesnastkowej Else 'w przeciwnym razie Print "Dane nieprawidlowe" 'wyslanie do terminala tekstu Exit For 'opuszczenie petli For End If Next I 'zwiekszenie o 1 wartosci I End 'koniec programu Sub Zap_eeprom(byval Adres As Word , Byval Dana As Byte) 'procedura zapisu danej do EEPROM Zm_pom = Adres / 256 'obliczenie adresu strony Temp = Low(zm_pom) 'zapis do temp mniej znaczacego bajta zmiennej zm_pom Adres = Adres Mod 256 'obliczenie adresu komorki pamieci Shift Temp , Left , 1 'przesuniecie wartosci w temp o jedna pozycje w lewo (mnozenie przez 2) Temp = Temp + Adr_w 'obliczenie adresu pamieci z uwzglednieniem stron I2cstart 'start transmisji I2cwbyte Temp 'zapis adresu ukladu pamieci do zapisu I2cwbyte Adres 'adres komorki pamieci I2cwbyte Dana 'zapis danej I2cstop 'koniec transmisji Waitms 7 'opoznienie 7 ms End Sub 'koniec procedury Sub Odc_eeprom(byval Adres As Word , Dana As Byte) 'procedura odczytu danej do EEPROM Zm_pom = Adres / 256 'obliczenie adresu strony Temp = Low(zm_pom) 'zapis do temp mniej znaczacego bajta zmiennej zm_pom Adres = Adres Mod 256 'obliczenie adresu komorki pamieci Shift Temp , Left , 1 'przesuniecie wartosci w temp o jedna pozycje w lewo (mnozenie przez 2) Temp = Temp + Adr_w 'obliczenie adresu pamieci z uwzglednieniem stron I2cstart 'start transmisji I2cwbyte Temp 'zapis adresu ukladu pamieci do zapisu I2cwbyte Adres 'adres komorki pamieci I2cstart 'ponowny start transmisji Incr Temp 'zwiekszenie temp o jeden - uzyskanie adresu do odczytu danej z pamieci I2cwbyte Temp 'zapis adresu ukladu pamieci do odczytu I2crbyte Dana , Nack 'odczyt bajta danej - bez potwierdzenia sygnałem ACK I2cstop 'koniec transmisji End Sub 'koniec procedury

Na list. 2 przedstawiono sposób obsługi pamięci AT24C16. Działanie programu jest podobne jak poprzedniego, z tym, że do każdej 256 bajtowej strony jest zapisywany jej numer. Procedury zapisu danych do pamięci oraz odczytu z niej różnią się tylko zakresem wartości adresu (adres od 0 do 2047) oraz zapisaniem adresu strony na bitach P2...P0.

Jedną z większych pamięci pod względem pojemności jest AT24C64 (pojemność 8 kB). Pamięć ma 3 linie adresowe wyboru układu a więc w tej pamięci słowo adresowe jest identyczne, jak w pamięciach AT24C02, czyli można ją wybrać poprzez zewnętrzne linie A2...A0. Ponieważ pamięć ta ma pojemność 8 kB, która została podzielona na 32 strony 256–bajtowe, to do ich zaadresowania są potrzebne dwa bajty, a nie jeden jak w AT24C02.

Listing 3. 'Program komunikujący się z pamięcia 24C64 (8k - 256*32) - pojemność 8192 bajtów 'Komunikacja z pamiecia odbywa sie przy pomocy magistrali I2C 'Mikrokontroler ATMEGA8 taktowany z czestotliwoscia 8MHz 'Pamiec posiada 32 strony z ktorych kazda ma 256 komorek co daje pojemność 8kB (8192 komorek) 'W programie do pamieci (komorki 0...8192) wpisywane sa wartosci liczbowe numerow stron do których nastepuje zapis. 'Nastepnie dane zapisane do pamieci sa odczytywane i weryfikowane pod wzgledem poprawnosci zapisu 'Zarowno wartosci danych zapisywanych jak i odczytywanych sa wysylane do terminala poprzez interfejs RS232. 'Predkosc komunikacji przez RS232 wynosi 38400 bodow. 'W przypadku bledu zapisu do pamieci wysylany jest do terminala stosowny komunikat 'Marcin Wiązania 'marcin.wiazania@ep.com.pl $regfile = "m8def.dat" 'informuje kompilator o pliku dyrektyw mikrokontrolera $crystal = 8000000 'informuje kompilator o częstotliwości oscylatora taktujacego mikrokontroler $baud = 38400 'informuje o predkosci transmisji interfejsu RS232 Const Adr_w = 160 'adres zapisu danej do pamieci EEPROM Const Adr_r = 161 'adres odczytu danej do pamieci EEPROM Config Sda = Portc.4 'konfiguracja linii SDA interfejsu I2C Config Scl = Portc.3 'konfiguracja linii SCL interfejsu I2C Config I2cdelay = 5 'konfiguracja opoznienia (czestotliwosci) linii zegarowej SCL Declare Sub Zap_eeprom(byval Adres As Word , Byval Dana As Byte) 'procedura zapisu danej do pamieci Declare Sub Odc_eeprom(byval Adres As Word , Dana As Byte) 'procedura odczytu danej z pamieci Dim Adres As Word 'zmienna adresu komorki pamieci Dim Adr_h As Byte 'bardziej znaczaca polowka adresu Dim Adr_l As Byte 'mniej znaczaca polowka adresu Dim Dana As Byte 'zmienna zmienna na odczytana lub zapisana dana do pamieci Dim I As Byte 'zmienna licznikowa Dim J As Byte 'zmienna licznikowa Print "Zapis" 'wyslanie do terminala tekstu I = 0 'zerowanie zmiennej I J = 0 'zerowanie zmiennej J For Adres = 0 To 8191 'petla wykonywana dla I=0 do I=255 Call Zap_eeprom(adres , J) 'zapis do EEPROM wartosci zmiennej I pod adres wskazywany przez I Print Hex(j) ; " "; 'wyslanie do terminala wartosci zapisywanej do EEPROM w postaci szesnastkowej Incr I 'zwiekszenie o jeden zmiennej I If I = 0 Then 'jesli I=0 to Incr J 'zwiekszenie o jeden zmiennej J End If Next I 'zwiekszenie o 1 wartosci I Print 'wyslanie do terminala wiersza odstepu Print "Odczyt i weryfikacja" 'wyslanie do terminala tekstu I = 0 'zerowanie zmiennej I J = 0 'zerowanie zmiennej J For Adres = 0 To 8191 'petla wykonywana dla I=0 do I=255 Call Odc_eeprom(adres , Dana) 'odczytanie z EEPROM wartosc z komorki o adresie wskazywanym przez I If Dana = J Then '--weryfikacja danych-- jesli Dana = I to Print Hex(dana) ; " "; 'wyslanie do terminala odczytanej wartosci z pamieci w postaci szesnastkowej Else 'w przeciwnym razie Print "Dane nieprawidlowe" 'wyslanie do terminala tekstu Exit For 'opuszczenie petli For End If Incr I 'zwiekszenie o jeden zmiennej I If I = 0 Then 'jesli I=0 to Incr J 'zwiekszenie o jeden zmiennej J End If Next I 'zwiekszenie o 1 wartosci I End 'koniec programu Sub Zap_eeprom(byval Adres As Word , Byval Dana As Byte) 'procedura zapisu danej do EEPROM Adr_h = High(adres) 'zapis do Adr_h bardziej znaczacej polowki adresu Adr_l = Low(adres) 'zapis do Adr_l mniej znaczacej polowki adresu I2cstart 'start transmisji I2cwbyte Adr_w 'zapis adresu ukladu pamieci do zapisu I2cwbyte Adr_h 'bardziej znaczacy adres komorki pamieci I2cwbyte Adr_l 'mniej znaczacy adres komorki pamieci I2cwbyte Dana 'zapis danej I2cstop 'koniec transmisji Waitms 7 'opoznienie 7 ms End Sub 'koniec procedury Sub Odc_eeprom(byval Adres As Word , Dana As Byte) 'procedura odczytu danej do EEPROM Adr_h = High(adres) 'zapis do Adr_h bardziej znaczacej polowki adresu Adr_l = Low(adres) 'zapis do Adr_l mniej znaczacej polowki adresu I2cstart 'start transmisji I2cwbyte Adr_w 'zapis adresu ukladu pamieci do zapisu I2cwbyte Adr_h 'bardziej znaczacy adres komorki pamieci I2cwbyte Adr_l 'mniej znaczacy adres komorki pamieci I2cstart 'ponowny start transmisji I2cwbyte Adr_r 'zapis adresu ukladu pamieci do odczytu I2crbyte Dana , Nack 'odczyt bajta danej - bez potwierdzenia sygnałem ACK I2cstop 'koniec transmisji End Sub 'koniec procedury

Na list. 3 przedstawiono przykładowy program obsługi pamięci AT24C64. Także w tym programie do pamięci są zapisywane numery stron pamięci, do których następuje zapis. Zakres adresów zawiera się w przedziale od 0 do 8191.

Rys. 8. Ramka zapisu komórki pamięci AT24C64
Rys. 9. Ramka odczytu jednej komórki pamięci AT24C64

Na rys. 8 przedstawiono ramkę z sygnałami dla zapisu bajtu pamięci, natomiast na rys. 9 ramkę do odczytu jednego bajtu pamięci. Po wysłaniu adresu pamięci powinien zostać wysłany adres składający się z dwóch bajtów. W przykładowym programie zarówno dane zapisywane jak i odczytywane z pamięci są wysyłane do terminala. Odczytywane dane są także w tym przypadku poddawane weryfikacji.

Pamięci z rodziny AT24Cxx są dosyć często wykorzystywane ze względu na łatwość obsługi i podłączenia do mikrokontrolera oraz trwałość. Ponadto do jednej magistrali może być dołączonych kilka pamięci AT24Cxx z różnie skonfigurowanymi adresami.

Tego typu pamięci można wykorzystać nie tylko do zapamiętywania danych konfiguracyjnych urządzenia, ale mogą także być wykorzystywane jako pamięci rejestrujące spore ilości danych.

Pamięci szeregowe EEPROM z rodziny 93Cxx

Pamięci te są zazwyczaj wykorzystywane do zapamiętywania konfiguracji urządzeń. Mają wbudowany interfejs szeregowy SPI.

Rys. 10. Schemat blokowy pamięci 93C46

W ramach przykładu zostanie przedstawiona obsługa pamięci 93C46 o pojemności 128 bajtów, której schemat blokowy przedstawiono na rys. 10.

Rys. 11. Schemat dołączenia pamięci AT93C46 do mikrokontrolera ze zwartymi liniami danych A i D

Na rys. 11 przedstawiono schemat sposobu dołączenia pamięci AT93C46 do mikrokontrolera w układzie testowym. Linia CS, jest linią wyboru pamięci, linia CLK jest linią zegarową, linia DI jest wejściem danych, a linia DO wyjściem. Linia ORG umożliwia wybór organizacji danych. Gdy linia ORG jest zwarta do plusa zasilania, dane będą 16–bitowe, a przy zwartej do masy 8–bitowe. W przykładzie została wybrana organizacja 8–bitowa pamięci. Pamięć AT93C46 można podłączyć do mikrokontrolera na dwa sposoby. Ze zwartymi liniami danych DI i DO jak na schemacie z rys. 11 lub z rozdzielonymi liniami danych DI i DO jak pokazano to na rys. 12.

Rys. 12. Schemat dołączenia pamięci AT93C46 do mikrokontrolera z rozdzielonymi liniami danych A i D

W pierwszym przypadku wymagane są 3 linie mikrokontrolera, natomiast w drugim 4 linie.

Komunikacja z pamięcią odbywa się za pomocą komend, które zestawiono w tab. 2. Każda z komend składa się z jej kodu, adresu oraz także 8–bajtowej danej dla komendy żądania odczytu (przy linii ORG zwartej do masy). Komenda ERASE zeruje wybrane słowo pamięci, natomiast komenda ERAL zeruje całą pamięć. Komenda EWDS umożliwia zablokowanie zapisu do pamięci. Do odblokowania pamięci przed zapisem służy komenda EWEN. Do odczytu danej z pamięci służy komenda READ, a do zapisu WRITE. Komenda WRAL umożliwia zapis całej pamięci EEPROM wybraną wartością danej.

Listing 4. 'Program komunikujący się z pamięcia AT93C46 (1k - 128*8) - pojemność 128 bajtów 'Komunikacja z pamiecia odbywa sie przy pomocy magistrali SPI 'Mikrokontroler ATMEGA8 taktowany czestotliwoscia 8MHz 'W programie do pamieci (komorki 0...127) wpisywane sa wartosci liczbowe od 0 do 127, 'nastepnie dane zapisane do pamieci sa odczytywane i weryfikowane pod wzgledem poprawnosci zapisu 'zarowno wartosci danych zapisywanych jak i odczytywanych sa wysylane do terminala poprzez interfejs RS232. 'Predkosc komunikacji przez RS232 wynosi 9600 bodow. 'W przypadku bledu zapisu do pamieci wysylany jest do terminala stosowny komunikat 'Marcin Wiązania 'marcin.wiazania@ep.com.pl $regfile = "m8def.dat" 'informuje kompilator o pliku dyrektyw mikrokontrolera $crystal = 8000000 'informuje kompilator o częstotliwości oscylatora taktujacego mikrokontroler $baud = 9600 'informuje o predkosci transmisji interfejsu RS232 Config Pinb.5 = Output 'linia PB5 jako wyjsciowa Config Pinb.2 = Output 'linia PB2 jako wyjsciowa Config Pinb.3 = Output 'linia PB3 jako wyjsciowa Declare Sub Zap_eeprom(byval Adres As Byte , Byval Dana As Byte) 'procedura zapisu danej do pamieci Declare Sub Odc_eeprom(byval Adres As Byte , Dana As Byte) 'procedura odczytu danej z pamieci Declare Sub Zap_en 'procedura odblokowania kasowania oraz zapisu pamieci Declare Sub Zap_bl 'procedura zablokowania kasowania oraz zapisu pamieci Declare Sub Res_pam 'procedura zerowania pamieci Declare Sub Opozn_zap 'procedura opoznienia potrzebnego na czas zapisu do pamieci Dim Adres As Byte 'zmienna adresu komorki pamieci Dim Dana As Byte 'zmienna zmienna na odczytana lub zapisana dana do pamieci Dim I As Byte 'zmienna licznikowa Dim Temp As Byte 'zmienna pomocnicza Sk Alias Portb.5 'przypisanie nazwie Portb.5 aliasu Sk Cs Alias Portb.2 'przypisanie nazwie Portb.2 aliasu Cs Od Alias Portb.3 'przypisanie nazwie Portb.3 aliasu Od Di Alias Pinb.3 'przypisanie nazwie Pinb.3 aliasu Di Reset Cs 'zerowanie linii Cs Reset Sk 'zerowanie linii Sk Set Od 'ustawienie linii Od (linia DO) Call Zap_en 'odblokowanie mozliwosci kasowania oraz zapisu do pamieci Call Res_pam 'czyszczenie zawartosci pamieci Print "Zapis" 'wyslanie do terminala tekstu For I = 0 To 127 'petla wykonywana dla I=0 do I=255 Call Zap_eeprom(i , I) 'zapis do EEPROM wartosci zmiennej I pod adres wskazywany przez I Print Hex(i) ; " "; 'wyslanie do terminala wartosci zapisywanej do EEPROM w postaci szesnastkowej Next I 'zwiekszenie o 1 wartosci I Print 'wyslanie do terminala wiersza odstepu Print "Odczyt i weryfikacja" 'wyslanie do terminala tekstu For I = 0 To 127 'petla wykonywana dla I=0 do I=255 Call Odc_eeprom(i , Dana) 'odczytanie z EEPROM wartosc z komorki o adresie wskazywanym przez I If Dana = I Then '--weryfikacja danych-- jesli Dana = I to Print Hex(dana) ; " "; 'wyslanie do terminala odczytanej wartosci z pamieci w postaci szesnastkowej Else 'w przeciwnym razie Print "Dane nieprawidlowe" 'wyslanie do terminala tekstu Exit For 'opuszczenie petli For End If Next I 'zwiekszenie o 1 wartosci I Call Zap_bl 'zablokowanie mozliwosci kasowania oraz zapisu do pamieci End 'koniec programu Sub Opozn_zap 'procedura opoznienia potrzebnego na czas zapisu do pamieci Set Od 'ustawienie linii Do Set Cs 'ustawienie linii Cs Waitms 12 'opoznienie 12 ms Reset Cs 'zerowanie linii Cs End Sub 'koniec procedury Sub Res_pam 'procedura zerowania pamieci Set Cs 'ustawienie linii Cs Set Od 'ustawienie linii Do Temp = &B10000000 'kod rozkazu zerowania pamieci Shiftout Od , Sk , Temp , 1 , 3 , 1 'wyslanie 3 bitow zmiennej Temp do pamieci Temp = &B10000000 'dalszy kod rozkazu zerowania pamieci Shiftout Od , Sk , Temp , 1 , 7 , 1 'wyslanie 7 bitow zmiennej Temp do pamieci Reset Cs 'zerowanie linii Cs Call Opozn_zap 'wywolanie procedury opoznienia End Sub 'koniec procedury Sub Zap_en 'procedura odblokowania kasowania oraz zapisu pamieci Set Cs 'ustawienie linii Cs Set Od 'ustawienie linii Do Temp = &B10000000 'kod rozkazu odblokowania zerowania i zapisu do pamieci Shiftout Od , Sk , Temp , 1 , 3 , 1 'wyslanie 3 bitow zmiennej Temp do pamieci Temp = &B11000000 'dalszy kod rozkazu odblokowania zerowania i zapisu do pamieci Shiftout Od , Sk , Temp , 1 , 7 , 1 'wyslanie 7 bitow zmiennej Temp do pamieci Reset Cs 'zerowanie linii Cs End Sub 'koniec procedury Sub Zap_bl 'procedura blokowania kasowania oraz zapisu pamieci Set Cs 'ustawienie linii Cs Set Od 'ustawienie linii Do Temp = &B10000000 'kod rozkazu blokowania zerowania i zapisu do pamieci Shiftout Od , Sk , Temp , 1 , 3 , 1 'wyslanie 3 bitow zmiennej Temp do pamieci Temp = &B00000000 'dalszy kod rozkazu blokowania zerowania i zapisu do pamieci Shiftout Od , Sk , Temp , 1 , 7 , 1 'wyslanie 7 bitow zmiennej Temp do pamieci Reset Cs 'zerowanie linii Cs End Sub 'koniec procedury Sub Zap_eeprom(byval Adres As Byte , Byval Dana As Byte) 'procedura zapisu danej do EEPROM Temp = &B10100000 'kod rozkazu zapisu danej do pamieci Set Cs 'ustawienie linii Cs Set Od 'ustawienie linii Do Shiftout Od , Sk , Temp , 1 , 3 , 1 'wyslanie 3 bitow zmiennej Temp do pamieci Shift Adres , Left , 1 'przesuniecie bitow zmiennej Adres o jedna pozycje w lewo Shiftout Od , Sk , Adres , 1 , 7 , 1 'wyslanie 7 bitow zmiennej Adres do pamieci Shiftout Od , Sk , Dana , 1 , 8 , 1 'wyslanie zmiennej Dana do pamieci Reset Cs 'zerowanie linii Cs Call Opozn_zap 'wywolanie procedury opoznienia End Sub 'koniec procedury Sub Odc_eeprom(byval Adres As Byte , Dana As Byte) 'procedura odczytu danej do EEPROM Temp = &B11000000 'kod rozkazu odczytu danej z pamieci Set Cs 'ustawienie linii Cs Set Od 'ustawienie linii Do Shiftout Od , Sk , Temp , 1 , 3 , 1 'wyslanie 3 bitow zmiennej Temp do pamieci Shift Adres , Left , 1 'przesuniecie bitow zmiennej Adres o jedna pozycje w lewo Shiftout Od , Sk , Adres , 1 , 7 , 1 'wyslanie 7 bitow zmiennej Adres do pamieci Reset Ddrb.4 'ustawienie linii PB4 jako wejscie Shiftin Di , Sk , Dana , 0 , 8 , 1 'odczyt bajta danych z pamieci do zmiennej Dana Reset Cs 'zerowanie linii Cs Set Ddrb.4 'ustawienie linii PB4 jako wyjscie Set Od 'ustawienie linii Do End Sub 'koniec procedury

Na list. 4 przedstawiono program obsługujący pamięć 93C46. Wpisuje on do poszczególnych słów pamięci od 0 do 127 ich adresy, czyli kolejno wartości od 0 do 127.

Rys. 13. Ramka podczas odczytu danej z pamięci AT93C46

Na rys. 13 przedstawiono ramkę z sygnałami podczas odczytu danej, a na rys. 14 podczas zapisu danej do pamięci. W programie zapis danej do pamięci realizuje procedura Zap_eeprom mająca parametry: adres i dana. Po zapisie danej jest wywoływana procedura opóźnienia Opozn_zap. Opóźnienie jest wymagane, gdyż zapis słowa pamięci trwa nawet do kilkunastu ms.

Rys. 14. Ramka podczas zapisu danej do pamięci AT93C46

Procedura Odc_eeprom mająca także dwa parametry, umożliwia odczyt danej z wybranej adresem słowa pamięci. Procedura Zap_en odblokowuje zapis pamięci, a procedura Zap_bl blokuje zapis.

Procedura Res_pam zeruje cała pamięć. W tej procedurze także wywoływana jest procedura opóźnienia ze względu, że zerowanie pamięci trwa kilkanaście ms. W pierwszej kolejności w programie pamięć zostaje odblokowana, po czym następuje jej zerowanie. Po zapisie oraz odczycie danych z pamięci następuje jej zablokowanie. Zarówno dane zapisywane jak i odczytywane z pamięci są wysyłane do komputerowego terminala. Podczas odczytu danych z pamięci jest realizowana ich weryfikacja.

Pamięci z rodziny 93C46 są często wykorzystywane do zapamiętywania parametrów konfiguracyjnych urządzeń, których niewielka pojemność do tego celu wystarcza. Pamięci te nie są wykorzystywane do przechowywania dużych ilości danych. Do tego celu idealnie nadają się pamięci DataFlash.

Marcin Wiązania
marcin.wiazania@ep.com.pl

Artykuł ukazał się w
Listopad 2005
DO POBRANIA
Pobierz PDF Download icon
Materiały dodatkowe
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik marzec 2025

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio marzec - kwiecień 2025

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje marzec 2025

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna luty 2025

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich marzec 2025

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik marzec 2025

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio marzec - kwiecień 2025

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje marzec 2025

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna luty 2025

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich marzec 2025

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik marzec 2025

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio marzec - kwiecień 2025

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje marzec 2025

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna luty 2025

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich marzec 2025

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów