background image

http://www.easy-soft.tsnet.pl/

PAMIĘCI FRAM W ZASTOSOWANIACH 

PRAKTYCZNYCH. PAMIĘĆ SZEREGOWA FM24C64

Wprowadzenie.

Współcześnie pamięci dzielone są na dwie kategorie. Pierwszą z nich są pamięci nieulotne. Od wielu lat używane 

są   w   aplikacjach   w   celu   zapamiętania   pewnych   stałych,   niezmiennych   informacji.   Może   to   być   program 

realizowany przez mikroprocesor, czy też dla przykładu wzorce znaków wyświetlanych na ekranie wyświetlacza 

LCD. Podstawową cechą tego rodzaju pamięci jest stałość przechowywanych informacji również, gdy brak jest 

napięcia zasilania. Zazwyczaj  zapis pamięci  stałej  (często zwany  jej programowaniem),  nawet  mimo użycia 

technologii EEPROM czy też FLASH EEPROM, jest dosyć trudny i zajmuje dużo czasu, jeśli odnieść to do czasu 

odczytu tejże pamięci. 
Druga grupa to pamięci ulotne, tak zwane RAM. Są one łatwe do zapisu i pracują bardzo szybko, więc ten rodzaj 

pamięci przechowuje dane, które często ulegają zmianie. Przeciwnie do pamięci ROM, dane przechowywane w 

pamięci   RAM   giną   po   odłączeniu   napięcia   zasilającego   i   jeśli   konieczne   jest   z   jakiś   względów   zachowanie 

niezmiennego stanu RAM, wymagane jest stosowania pomocniczych źródeł zasilania. Jest to swego rodzaju 

wyzwanie dla konstruktora układu.
Wad   wyżej   opisanych   układów   nie   posiada   nowy   rodzaj   pamięci,   której   technologia   wytwarzania   przed 

kilkunastu laty opuściła laboratoria naukowe. Jest to pamięć FRAM. Skrót nazwy tłumaczy się jako Ferroelectric 

Random Access Memory. Oznacza on technologię wytwarzania (uwaga!) nieulotnej pamięci RAM, czyli pamięci 

łączącej w sobie szybkość pracy RAM i trwałość ROM.
Pamięci wytwarzane w technologii FRAM dostępne były już przed kilku laty (praktycznie od 1993 roku), ale 

zarówno cena jak i dostępny asortyment nie zachęcały do ich stosowania. Jednak w ostatnim czasie technologia 

ta przeżywa prawdziwą eksplozję rozwoju. Firmy oferują liczne układy peryferyjne wyposażone w pamięci FRAM 

a   cena   układów   gwałtownie   spada.   Moim   zdaniem   w   przyszłości   technologia   ta   może   zastąpić   popularną 

technologię FLASH EEPROM chyba, że zostanie opracowany jakiś zupełnie nowy rodzaj pamięci.

Czym są pamięci FRAM?

FRAM jest rodzajem pamięci RAM, w której wykorzystano efekt ferroelektryczny do zapamiętywania bitów słowa 

danych. Efekt ten, być może znany niektórym studentom politechnik z ćwiczeń w laboratorium fizyki, występuje 

w niektórych materiałach krystalicznych i jest zdolnością materiału do przechowywania polaryzacji elektrycznej 

również   w   przypadku   nieobecności   pola   elektrycznego,   które   tę   polaryzację   wywołało.   Komórka   pamięci 

tworzona   jest   poprzez   nałożenie   materiału   ferroelektrycznego   w   postaci   krystalicznej   pomiędzy   dwa 

doprowadzenia   płaskich   elektrod   w   taki   sposób,   aby   został   utworzony   kondensator   z   materiałem 

ferroelektrycznym   jako   dielektrykiem.   Konstrukcja   tego   kondensatora   zbliżona   jest   do   typowej   konstrukcji 

komórki pamięci DRAM z tym, że zamiast przechowywać informację w postaci naładowanego kondensatora (tak, 

jak   w   typowo   robi  to   komórka   pamięci   DRAM),   bit   przechowywany   jest   w   postaci   polaryzacji  ładunków   w 

obrębie   struktury   krystalicznej.   W   ten   sposób   –   poprzez   zmianę   polaryzacji   ładunków   przy   pomocy   pola 

elektrycznego wewnątrz  kondensatora,  można  tworzyć i  zapamiętać  dwa  stabilne stany.  Stany  te  umownie 

mogą odpowiadać wartościom logicznym bitów, to jest „zeru” i „jedynce”.
Prosta zasada działania, niemalże identyczna z tą stosowaną w pamięciach RAM, umożliwia konstrukcję prostych 

obwodów zapisu i odczytu komórek pamięci. Jak wspomniano wcześniej, materiał ferroelektryczny zachowuje 

polaryzację ładunków pomimo zaniku pola elektrycznego i w związku tym, nie tak jak w pamięciach RAM, dane 

mogą   być   przechowywane   w   sposób   nieulotny.   Zbudowana   z   jego   wykorzystaniem   komórka   pamięci   nie 

wymaga również okresowego odświeżania.
Pamięć   FRAM   jest   odporna   na   działania   zewnętrznego   pola 

magnetycznego. Jej zasada działania, nie ma nic wspólnego z 

ferromagnetyzmem.   Podobny   jest   jedynie   opis   zjawiska 

fizycznego:   w   przypadku   materiałów   ferroelektrycznych 

polaryzacji ulegają ładunki, natomiast w przypadku materiałów 

ferromagnetycznych – domeny magnetyczne.

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 1/12

Rys.1. Budowa kryształu ferro-

elektrycznego - perowskitu.

background image

http://www.easy-soft.tsnet.pl/

Praca pamięci FRAM.

Na   rysunku   1   przedstawiony   jest   poglądowy   model   kryształu   ferroelektrycznego   o   strukturze   perowskitu. 

Kryształ   posiada   ruchomy   atom   w   środku   swojej   struktury   (oznaczony   kolorem   żółtym).   Przyłożenie   pola 

elektrycznego powoduje, że „mobilny” atom  przesuwa się w kierunku działania sił pola. Odwrócenie polaryzacji 

pola powoduje przemieszczanie się atomu w kierunku przeciwnym. Pozycje atomy na „górze” i „dole” struktury 

krystalicznej są stabilne. Atom pozostaje w jednej z nich w przypadku braku pola elektrycznego. Jako komórka 

pamięci cyfrowej, taka struktura jest wręcz idealna: posiada dwa stany stabilne, potrzebuje bardzo małej mocy 

do zmiany stanu i zachowuje ten stan nawet mimo działania różnych czynników zewnętrznych.

Odczyt.

Mimo, iż podstawowym elementem komórki 

pamięci jest kondensator, to jednak bity nie 

są   zapamiętywane   jako   ładunek   liniowy. 

Odczyt   takiej   komórki   pamięci   wymaga 

detekcji położenia atomu wewnątrz struktury 

krystalicznej.   Niestety   nie   może   ono   być 

rozpoznane   bezpośrednio   i   musi   tu   być 

używany pewien „zabieg”. 
Do kondensatora przykładane jest napięcie. 

Na  skutek  tego  pomiędzy  jego okładzinami 

pojawia się pole elektryczne. Ruchomy atom 

przesuwa się zgodnie z kierunkiem działania 

pola, lub pozostaje w spoczynku, jeśli jego 

położenie   jest   z   nim   zgodne.   W   środku 

struktury   kryształu   występuje   stan 

równowagi,   który   utrzymuje   pozostałe 

atomy w ściśle określonych położeniach sieci 

krystalicznej   a   wypadowe   pole   elektryczne 

jest   równe   0.   Jeśli   ruchomy   atom 

przemieszcza   się,   to   powoduje   zaburzenie, 

co   skutkuje   impulsem   energetycznym. 

Impuls   ten   dodaje   się   do   ładunku 

zgromadzonego

 

przez

 

kondensator 

(pamiętajmy,   że   opisywane   są   struktury   o 

rozmiarach kilkunastu atomów!). Na skutek 

tego   jedne   kondensatory   naładowane   będą 

do wartości ładunku wymuszonej przez pole 

elektryczne   a   inne   będą   posiadać   ładunek 

będący   kombinacją   oddziaływania   pola 

elektrycznego   i   ruchu   atomu.   Mimo,   iż 

odczyt   pamięci   wymaga   przemieszczenia 

atomu, to jednak należy pamiętać o tym, że 

atom   przebywa   bardzo   krótką   drogę.   Jego 

położenie   zmienia   się   w   czasie   1 

nanosekundy (10

-9

 sekundy) a cała operacja 

odczytu zajmuje około 70 nanosekund.
Łatwo   na   podstawie   powyższego   opisu 

wywnioskować, jak  będzie  wyglądać obwód 

określający   stan   bitu:   będzie   to   rodzaj 

komparatora   porównującego   ładunek 

odebrany   z   komórki   pamięci   z   pewnym 

poziomem   odniesienia.   Dobrze,   a   co   ze 

zmianą   polaryzacji   ładunku?   Przecież 

pisałem,   że   podczas   odczytu   atom 

przemieszcza   się   wewnątrz   struktury.   W 

związku   z   przyjętą   metodą   odczytu, 

każdemu   cyklowi   dostępu   do   pamięci 

towarzyszy rodzaj operacji odświeżania. A co 

w   związku   z   tym   z   czasem   dostępu   do 

pamięci? Czy  nie jest  przez  to odświeżanie 

wydłużany? Niestety tak. Wpływ odświeżania 

na czas odczytu pamięci FRAM jest znaczny, 

ponieważ zajmuje ono aż 50 nanosekund.

Zapis.

Operacja   zapisu   jest   bardzo   podobna   do 

opisywanego wcześniej odczytu. Inaczej niż 

inne rodzaje pamięci stałych programowane 

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 2/12

 

 

 

Rysunki pochodzące ze strony internetowej firmy RAMTRON. 
(http://www.ramtron.com). Od góry:

zasada działania komórki pamięci,

struktura komórki pamięci FRAM,

rozwój technologii produkcji układów.

background image

http://www.easy-soft.tsnet.pl/

elektrycznie, nie wymaga przyłożenia wysokiego napięcia czy też długiego czasu zapisu. Wewnętrzny obwód 

przykłada   napięcie   do   okładzin  kondensatora   ferroelektrycznego.   Powoduje   to   odpowiednie  przemieszczenie 

ruchomego   atomu   i   polaryzację   kryształów.   Jeśli   jest   to   potrzebne,   nowe   dane   po   prostu   zmieniają   stan 

polaryzacji kryształu ferroelektrycznego. Tak, jak w przypadku odczytu, zmiana stanu kryształu zajmuje ok. 1 

nanosekundy podczas, gdy cała operacja zapisu około 70 nanosekund (7 x 10

-8

s!). Nieporównywalnie krótki 

czas, jeśli odnieść go np. do pamięci FLASH.

Aplikacje.

Oczywiście,   w   praktyce,   wszystkie   opisywane   wyżej   zjawiska   nie   będą 

obchodzić   potencjalnego   użytkownika   układu.   Producenci   wyposażając 

układ peryferyjny w interfejs SPI zwalniają konstruktora od pamiętania o 

fizycznych   cechach   pamięci.   Nieco   inaczej   jest   w   przypadku   pamięci 

równoległych – poruszę ten temat w dalszej części artykułu.
Kiedy   po   raz   pierwszy   przeczytałem  o   upowszechnieniu  się   technologii 

pamięci FRAM, przed oczyma od razu miałem szerokie spektrum aplikacji. 

Po pierwsze, ze względu na bardzo dużą szybkość oraz ogromną liczbę 

cykli   zapisu,   bardzo   zasadne   jest   użycie   tego   rodzaju   pamięci   jako 

pamięci masowej w komputerach PC, telefonach komórkowych, aparatach 

fotograficznych   i   innych   urządzeniach   elektronicznych.   Moim   zdaniem 

pamięci   tego   rodzaju   mogą   z   powodzeniem   zastąpić   pamięć   FLASH   w 

mikrokontrolerach   tworząc   wspólny   obszar   pamięci   dla   danych   oraz 

programu.   Rzec   by   można,   że   im   mniejszy   będzie   kod   programu 

użytkownika, tym więcej pamięci RAM będzie miało do dyspozycji CPU 

mikrokontrolera.   To   nie   wszystko:   programy   będą   mogły   dynamicznie 

modyfikować   swój   stan   podczas   pracy   mikroprocesora.   Moim   zdaniem 

zupełnie zmieni  to  podejście  do  programowania  oraz  sposób   tworzenia 

aplikacji. To jest przyszłość. Niestety istnieją jeszcze pewne ograniczenie technologiczne i póki co pamięci FRAM 

dzielą się na dwie podstawowe kategorie. 
Pierwsza   to   typowe   aplikacje   do   przechowywania   danych.   W   nich   pamięci   FRAM   służą   do   zapamiętywania 

danych przechowywanych poza systemem. Drugi rodzaj aplikacji jest związany z konstrukcją i opracowywaniem 

urządzeń związanych z mikrokontrolerami i mikroprocesorami. Dzięki bardzo dużej szybkości zapisu, pamięci te 

mogą być wielokrotnie błyskawicznie zapisywane, znacznie skracając czas potrzebny na testowanie aplikacji 

podczas jej uruchamiania. Innym aspektem jest programowanie w czasie produkcji – znaczne skrócenie czasu 

zapisu   programu   obniża   koszty   wytwarzania   urządzenia.   Nie   jest   również   konieczne   wyposażanie   linii 

produkcyjnej w specjalne układy programatorów.

Produkty firmy RAMTRON.

Firmą   wiodącą   na   rynku   produktów   FRAM   i   praktycznie   założoną   tylko   w   celu   ich   rozwoju   oraz 

rozpowszechniania jest Ramtron International Corporation z siedzibą w Colorado Springs (USA). Firma założona 

została w  1984   roku i  po blisko  10  latach  prac badawczych,   w 1993  roku  wprowadziła na  rynek  pierwszy 

produkt komercyjny. Była to pamięć o pojemności 4 kb (kilo - bit). Współcześnie firma jest liderem w dziedzinie 

technologii wytwarzania pamięci FRAM, właścicielem wielu patentów z tej dziedziny i oferuje szereg różnych 

układów peryferyjnych. Między innymi układy zawierające np. zegar czasu rzeczywistego oraz 256 kb pamięci 

FRAM. Krótkie zestawienie jej produktów zawierają tabele 1 i 2.

Nazwa 
produktu

V

DD

Rodzaj 
interfejsu

Wielkość 
pamięci

RTC

RTC z 
funkcją 
Alarmu

Monitor 
zasilania

Watch 
Dog

Sygnali-
zacja 
zaniku 
napięcia

Numer 
seryjny

Przełącznik 
zasilania

Sygnali-
zacja 
zdarzenia

Rodzaj 
obudowy

Układy z rodziny 31: pamięć, RTC, układ kontroli, peryferia
FM31256

2.7-5.5V

Szer. 2-Wire 256Kb

Tak 

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

FM3164

2.7-5.5V 

Szer. 2-Wire 64Kb

Tak 

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

FM3116

2.7-5.5V

Szer. 2-Wire 16Kb

Tak 

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

FM3104

2.7-5.5V

Szer. 2-Wire 4Kb

Tak 

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

FM4005

2.7-5.5V

Szer. 2-Wire NA

Tak 

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

Układy z serii 32: kompatybilne z serią 31 ale bez RTC
FM32256

2.7-5.5V

Szer. 2-Wire 256Kb

Nie

Nie 

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik 

SOIC14

FM3264

2.7-5.5V

Szer. 2-Wire 64Kb

Nie

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

FM3216

2.7-5.5V

Szer. 2-Wire 16Kb

Nie

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

FM3204

2.7-5.5V

Szer. 2-Wire 4Kb

Nie

Nie

Tak 

Tak 

Tak 

Tak 

Tak 

Licznik

SOIC14

Pamięć, układ kontrolny, peryferia.
FM30C256 
5V

Szer. 2-Wire 256Kb

Tak 

Nie

Tak 

Nie

Nie

Nie

Tak 

-

SOIC20

FM3808DK 5V

Równoległy

32Kb x 8

Nie

Nie

No 

Nie

Nie

Nie

Nie

-

-

FM3808

5V

Równoległy

32Kb x 8

Tak 

Tak 

Tak 

Tak 

Nie

Nie

Tak 

Nie

TSOP32

Tabela 1. Układy peryferyjne do systemów z mikroprocesorem.

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 3/12

Główne zalety stosowania pamięci FRAM:

Cykl zapisu i cykl odczytu zajmują 
tyle samo czasu.

Można przeprowadzić ogromną ilość 
operacji zapisu i odczytu, ponieważ 
pamięć praktycznie nie zużywa się 
(gwarantowane jest 10

9

 cykli zapisu!).

Do zasilania wymagana jest bardzo 
mała moc. Odczyt i zapis pamięci 
wymaga jej dokładnie tak samo mało.

W związku z brakiem dodatkowych 
napięć zasilających i konieczności 
stosowania dodatkowego źródła 
zasilania pamięci RAM w celu 
podtrzymania zawartości pamięci, 
aplikacja ulega znacznemu 
uproszczeniu.

background image

http://www.easy-soft.tsnet.pl/

Nazwa 
produktu

Pojemność

Rodzaj 
obudowy

Maksymalna 
szybkość

V

DD

I

DD

Z interfejsem szeregowym 2-Wire
FM24C256

256Kb

8SE

1MHz

5V

1.2mA

FM24C64

64Kb

8S

1MHz

5V

1.2mA

FM24CL64

64Kb

8S 

1MHz

2.7-3.6V

400uA

FM24C16A

16Kb

8S

1MHz

5V

1.0mA

FM24CL16

16Kb

8S & DFN

1MHz

2.7-3.6V

400uA

FM24C04A

4Kb

8S

1MHz

5V

1.0mA

FM24CL04

4Kb

8S

1MHz

2.7-3.6V

300uA

Z interfejsem szeregowym SPI
FM25L256

256Kb

8S & DFN

25MHz

2.7-3.6V

6mA

FM25W256

256Kb

8S

25MHz

2.7-5.5V

7mA

FM25640

64Kb

8S

5MHz

5V

3.0mA

FM25CL64

64Kb

8S & DFN

20MHz

2.7-3.6V

10mA

FM25L16

16Kb

8S & DFN

20 MHz

2.7-3.6V

10mA

FM25C160

16Kb

8S

5MHz

5V

3mA

FM25CL04

4Kb

8S

20MHz

2.7V-3.6V

3.0mA

FM25040

4Kb

8S

1.8MHz

5V

2.5mA

Z interfejsem równoległym
FM18L08

32Kb x 8

28S, 28P

70ns

3.0-3.6V

15mA

FM1808

32Kb x 8

28S, 28P

70ns

5V 

25mA

FM1608

8Kb x 8

28S, 28P

120ns

5V 

15mA

Tabela 2. Układy pamięci FRAM.

Czas przejść do pokazania praktycznych zastosowań FRAM. Ten rodzaj pamięci mimo dostępności układów oraz 

niewątpliwych ich zalet, nie jest jeszcze w naszym  kraju zbyt popularny. Wiele z układów FRAM umożliwia 

zastąpienie   wprost   pamięci   EEPROM,   inne   wymagają   specjalnych   aplikacji   a   jeszcze   inne   są   całkowicie 

unikatowe.   Proponuję   aby   na   początek   zająć   się   typową   pamięcią   szeregową   z   interfejsem   2-Wire 

(kompatybilny z I

2

C) o pojemności 64 kbit.

Pamięć szeregowa FM24C64 (64 kbit).

Wykonana   w   technologii   FRAM   pamięć   FM24C64   wyposażona   jest   w   szybki   interfejs   2-Wire.   Jest   ona 

funkcjonalnym odpowiednikiem popularnej pamięci EEPROM produkowanej przez wiele firm pod oznaczeniem 

24C64 (np. przez firmę Atmel Corp. AT24C64). Jako, że ten rodzaj pamięci jest dobrze znany elektronikom, tu 

w   skrócie   zostaną   wymienione   cechy   pamięci   po   to,   aby   zająć   się   praktyczną   realizacją   interfejsu 

programowego umożliwiającego zapis i odczyt danych:

Bardzo niski pobór prądu: 150 μA przy zasilaniu 5V, 10 μA w trybie standby.

Organizacja: 8192 x 8 bit.

Możliwość wykonania aż 10

12

 cykli zapisu / odczytu!

Gwarancja na podtrzymanie zawartości przez 10 lat.

Brak czasu oczekiwania na zapis / odczyt bajtu (czas dostępu znacznie krótszy od okresu zegara 
transmisji interfejsu).

Częstotliwość sygnału zegarowego interfejsu do 1MHz.

Kompatybilna z pamięciami EEPROM typu 24C64.

Interfejs zbliżony funkcjonalnie do I

2

C (oba tryby: standardowy 100kHz i szybki 400kHz).

Jak wspomniano przy okazji krótkiej charakterystyki cech pamięci, jest ona kompatybilna z popularną pamięcią 

EEPROM   24C64.   Podobnie   jest   z   programem   obsługi:   nie   wymaga   on   żadnych   specjalnych   zabiegów. 

Najważniejsza jest różnica funkcjonalna: pamięć FRAM w porównaniu z EEPROM wyróżnia się ogromną wręcz 

szybkością zapisu. W związku z tym, że interfejs I

2

C jest znany z szeregu aplikacji, opis pamięci ograniczę do 

krótkiej charakterystyki funkcjonalnej. 
Podobnie jak I

2

C, kompatybilny z nim interfejs 2-Wire wymaga rezystorów zasilających (pull-up) o wartości 

minimalnej około 1,8kΩ. Wartość rezystorów zależy od pojemności połączeń. Przy bardzo krótkich połączeniach 

wystarczające mogą być rezystory wbudowane w strukturę np. mikrokontrolera, ale nie polecam rozwiązania 

tego typu.   Linie interfejsu są dwukierunkowe, transmisja zawsze nadzorowana jest przez układ zarządzający 

(master), podczas gdy pamięć jest zawsze układem nadzorowanym (slave). Podobnie jak w I

2

C linie noszą 

nazwę SDA (danych) i SCL (zegarowa). Od I

2

C przejęto również sygnalizację stanów (potwierdzenie odbioru 

danych czy komendy - ACK) oraz polecenia START, STOP.
Po otrzymaniu polecenia START interfejs pamięci oczekuje na 7-bitowy adres oraz bit kierunku transmisji (zapis 

/   odczyt).   W   8-bitowym   słowie   adresu,   bity   7   do   4   identyfikują   rodzaj   układu   i   są   predefiniowane   przez 

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 4/12

Dystrybutorem RAMTRON w Polsce jest firma: 
CIT International z Wrocławia 
(http://www.citworld.com/, info@citworld.com)

background image

http://www.easy-soft.tsnet.pl/

producenta. Bity 3 do 1 mogą być ustawiane przez użytkownika poprzez zwieranie odpowiednich wyprowadzeń 

do potencjałów „1” lub „0”. Najmłodszy bit 0 określa kierunek transmisji (0 – zapis, 1 – odczyt).
Na listingu 1 umieściłem funkcje obsługi zapisu i odczytu danych. Program w asemblerze 8051 napisany został 

na   podstawie   noty   aplikacyjnej   firmy   Atmel   przeznaczonej   dla   pamięci   AT24C64   (dla   EEPROM).   Jak 

wspomniałem wcześniej, oprócz bardzo dużej szybkości działania, pamięć FRAM nie różni się niczym w obsłudze 

od   swojego   odpowiednika   EEPROM.   Przykładowy   program   zapisuje   dane   do   pamięci   FRAM,   odczytuje   i 

weryfikuje   odczytaną   zawartość.   W   przypadku   niezgodności   linia   ERROROUT   (w   przykładzie   jest   to   P1.4) 

przyjmuje   stan   wysoki.   Program   źródłowy   zawiera   dużo   komentarzy   i   nie   jest   zbyt   trudny   do   analizy. 

Wymagana jest jedynie elementarna znajomość asemblera mikrokontrolera 8051.

Jacek Bogusz
jacek.bogusz@easy-soft.tsnet.pl

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 5/12

background image

http://www.easy-soft.tsnet.pl/

;------------------------------------------

;Funkcje obsługi pamięci 24C64

;------------------------------------------

;Dla mikrokontrolera z rodziny Intel 8051

;pracującego z zegarem 12MHz

$INCLUDE (REG_51.PDF)

;dołączenie definicji rejestrów uK (kompilator RA-51 Raisonance)

NAME

OBSLUGA_AT24C64

FIXEDADDR

EQU

0A0H

;stała część adresu pamięci 24C64

USRADDR

EQU

0

;ustawiana przez użytkownika część adresu (wartości 0..7)

MEMSIZE

EQU

2000H

;liczba bajtów dla 24C64

PMEMSIZE

EQU

32

;liczba bajtów na stronę pamięci dla 24C64

FILL

EQU

0AAH

;wartość używana w funkcji FILL do wypełnienia pamięci

;Definicje funkcji rejestrów

index

EQU

R0

;wskaźnik bufora w pamięci RAM mikrokontrolera

count

EQU

R1

;licznik bajtów

zdata

EQU

R2

;rejestr bajtu danych

addr_lo

EQU

R3

;młodszy bajt adresu bajtu w pamięci 24C64

addr_hi

EQU

R4

;starszy bajt - / / -    - / / -

;Definicje linii interfejsu

SCL

BIT

P1.2

;linia zegara (SCL)

SDA

BIT

P1.3

;linia danych (SDA)

ERROROUT

BIT

P1.4

;sygnalizacja błędu weryfikacji

;zmienne w pamięci RAM

DSEG AT 20H

buffer:

DS

PMEMSIZE

;bufor do zapisu / odczytu danych

DSEG AT 60H

;początek stosu

stack:

DS

20H

;rozmiar stosu

;tablica wektorów przerwań

CSEG

CODE AT 0000H

;wektor przerwania po RESET

ajmp

on_reset

CODE AT 0003H

;zewnętrzne przerwanie INT0

reti

CODE AT 000BH

;przerwanie TF0

reti

CODE AT 0013H

;zewnętrzne przerwanie INT1

reti

CODE AT 001BH

;przerwanie TF1

reti

CODE AT 0023H

;przerwanie od UART

reti

USING

0

;używany będzie bank rejestrów numer 0

CODE AT 0080H

;początek programu głównego

on_reset:

mov

SP,#(stack-1)

;inicjalizacja wskaźnika stosu

setb

SDA

;inicjalizacji linii interfejsu

setb

SCL

;SDA = SCL = 1

clr

ERROROUT

;ustawienie stanu niskiego wyjścia sygn.błędu

;< przykłady użycia funkcji >

call

byte_fill

;wypełnienie pamięci wartością FILL (0AAH)

jc

fault

;jeśli ustawiona flaga C, to błąd

call

verify_byte_fill

;weryfikacja zawartości

jc

fault

call

page_fill

;wypełnienie strony pamięci wartością FILL

jc

fault

;jeśli ustawiona flaga C, to błąd

call

verify_page_fill

;weryfikacja zawartości

jc

fault

jmp

$

fault:

setb

ERROROUT

;sygnalizacja błędu

jmp

$

;pętla nieskończona

;wypełnienie pamięci wartością zadeklarowaną jako FILL

;tryb stronnicowania nie jest wykorzystywany, zapisywany

;jest bajt po bajcie; ustawienie flagi CY wskazuje na przekroczenie

;limitu czasu operacji

;modyfikuje wartości A, B, DPTR, ADDR_HI (R2), ADDR_LO (R3), bit C

byte_fill:

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 6/12

background image

http://www.easy-soft.tsnet.pl/

mov

zdata,#FILL

mov

dptr,#0

;adres początkowy dla operacji zapisu

bf_x1:

mov

addr_lo,DPL

;ustawienie adresu bajtu w pamięci 24C64

mov

addr_hi,DPH

mov

B,#120

;licznik powtórzeń

bf_x2:

mov

A,#USRADDR

;do akumulatora zapisywana jest zmienna część adresu

call

write_byte

;próba zapisu

jnc

bf_x3

;skok, jeśli zapis pomyślny

djnz

B,bf_x2

;błąd, ponowna próba zapisu

setb

C

;zapis nie powiódł się, sygnalizacja błędu

jmp

bf_x4

;i wyjście

bf_x3:

inc

dptr

;następna pozycja w pamięci 24C64

mov

A,DPL

;sprawdzenie młodszego bajtu (limitu) dla adresów

cjne

A,#(LOW MEMSIZE),bf_x1;powtórnie, jeśli to nie ostatni bajt

mov

A,DPH

;sprawdzenie starszego bajtu adresu

cjne

A,#(HIGH MEMSIZE),bf_x1

;powtórnie, jeśli to nie ostatni bajt

clr

C

;zerowanie flagi sygnalizacji błędu

bf_x4:

ret

;koniec, pomyślna realizacja funkcji

;weryfikacja bajtów zapisanych w pamięci; odczytuje i sprawdza jeden

;bajt w danym momencie; używana jest funkcja Random Read do sprawdzenia

;zawartości pod pierwszym adresem oraz inicjalizacji wewnętrznego licznika

;adresów; następnie wywoływana jest Current Address Read i sprawdzana krok

;po kroku zawartość pamięci

;modyfikuje wartości A, B, DPTR, ADDR_HI (R2), ADDR_LO (R3), bit C

verify_byte_fill:

mov

DPTR,#0

;inicjalizacja rejestru adresów

mov

addr_lo,DPL

;zapamiętanie adresów

mov

addr_hi,DPH

mov

B,#120

;liczba powtórzeń

vbf_x1:

mov

A,#USRADDR

;załadowanie zmiennej części adresu

call

read_random

;próba odczytu

jnc

vbf_x2

;skok, jeśli pomyślna

djnz

B,vbf_x1

;błąd, powtórna próba odczytu

jmp

vbf_x6

;przekroczono limit, wyjście z ustawioną flagą CY

vbf_x2:

cjne

A,#FILL,vbf_x6

;skok, jeśli błąd porównania

jmp

vbf_x5

;następny adres w pamięci

vbf_x3:

mov

A, #USRADDR

call

read_current

;wywołanie funkcji odczytu bieżącego bajtu

jc

vbf_x6

;skok, jeśli operacja nie powiodła się

cjne

A,#FILL,vbf_x6

;skok, jeśli błąd porównania

vbf_x5:

inc

dptr

;następny adres w pamięci 

mov

A,DPL

;sprawdzenie młodszego bajtu (limitu) dla adresów

cjne

A,#(LOW MEMSIZE),vbf_x3

;powtórnie, jeśli to nie ostatni bajt

mov

A,DPH

;sprawdzenie starszego bajtu dla adresów

cjne

A,#(HIGH MEMSIZE),vbf_x3

;powtórnie, jeśli to nie ostatni bajt

clr

C

;zerowanie flagi sygnalizacji błędu

ret

;wyjście

vbf_x6:

setb

C

;ustawienie flagi sygnalizacji błędu

ret

;wypełnienie strony w pamięci wartością FILL

;modyfikuje wartości A, B, DPTR, ADDR_HI (R2), ADDR_LO (R3), bit C

page_fill:

mov

B,#PMEMSIZE

;do B liczba bajtów na stronę

mov

index,#buffer

;"index" jako wskaźnik do bufora w RAM mikrokontrolera

pf_x1:

mov

@index,#FILL

;wypełnienie bufora w RAM wartością FILL

inc

index

djnz

B,pf_x1

;zapis bufora do pamięci 24C64 - jedna strona

mov

dptr,#0

;inicjalizacji wskaźnika adresów

pf_x2:

mov

addr_lo,DPL

;nastawy rejestru adresów

mov

addr_hi,DPH

mov

count,#PMEMSIZE

;liczba bajtów na stronę

mov

B,#120

;rejestr B jako licznik powtórzeń

pf_x3:

mov

A,#USRADDR

;załadowanie programowanej części adresu

call

write_block

;próba zapisu

jnc

pf_x4

;skok, jeśli próba pomyślna

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 7/12

background image

http://www.easy-soft.tsnet.pl/

djnz

B,pf_x3

;ponowna próba zapisu

setb

C

;ustawienie flagi sygnalizacji błędu

jmp

pf_x6

;i wyjście

pf_x4:

;dodanie rozmiaru PMEMSIZE do wskaźnika adresów

mov

A,DPL

;dodawanie 2 bajtów (młodszy, później starszy)

add

A,#PMEMSIZE

mov

DPL,A

jnc

pf_x5

inc

DPH

;rozkaz INC DPH zastępuje dodanie do DPH przeniesienia

pf_x5:

cjne

A,#(LOW MEMSIZE),pf_x2;jak poprzednio-sprawdzenie adresu

mov

A,DPH

cjne

A,#(HIGH MEMSIZE),pf_x2

clr

C

pf_x6:

ret

;weryfikacja strony zapisanej w pamięci 24C64

;weryfikowana jest jedna strona w danym momencie

;modyfikuje wartości A, B, DPTR, ADDR_HI (R2), ADDR_LO (R3), bit C

verify_page_fill:

;przepisanie strony z pamięci 24C64 do bufora

mov

DPTR,#0

;inicjalizacja licznika adresów

vpf_x1:

mov

addr_lo,DPL

mov

addr_hi,DPH

mov

count,#PMEMSIZE

;liczba bajtów na stronę

mov

B,#120

;licznik powtórzeń

vpf_x2:

mov

A,#USRADDR

;zapamiętanie zmiennej części adresu

call

read_block

;próba odczytu

jnc

vpf_x4

;skok, jeśli pomyślna

djnz

B,vpf_x2

;ponowna próba odczytu

vpf_x3:

setb

C

;ustawienie bitu sygnalizacji błędu

jmp

vpf_x7

;wyjście

vpf_x4:

;weryfikacja zawartości bufora

mov

B,#PMEMSIZE

;liczba bajtów na stronę

mov

index,#buffer

;zapamiętanie adresu bufora w RAM

vpf_x5:

cjne

@index,#FILL,vpf_x3

;skok, jeśli błąd porównania

inc

index

;następna pozycja w buforze

djnz

B,vpf_x5

;dodanie PMEMSIZE do wskaźnika adresu

mov

A,DPL

;operacja przeprowadzana jak wyżej

add

A,#PMEMSIZE

mov

DPL,A

jnc

vpf_x6

inc

DPH

vpf_x6:

cjne

A,#(LOW MEMSIZE),vpf_x1

mov

A,DPH

cjne

A,#(HIGH MEMSIZE),vpf_x1

clr

C

vpf_x7:

ret

;zapis na stronie pamięci zawartości bufora BUFFER ;wywołanie:

;adres 1-go bajtu w ADDR_HI:ADDR_LO, dane do zapisu w BUFFER,

;liczba bajtów w COUNT, zmienna część adresu układu w A

;zwraca CY=1, jeśli magistrala jest zajęta lub pamięć nie odpowiada

;modyfikuje: A, COUNT, INDEX

write_block:

call

start

;wysłanie polecenie I2C START

jc

wb_x8

;przerwa, jeśli magistrala jest zajęta

rl

A

;zmienna część adresu przesuwana jest na poz. bitów 3:1

orl

A,#FIXEDADDR

;dodanie stałej części adresu

clr

ACC.0

;zerowanie bitu numer 0: zapis danych

call

shout

;wysłanie adresu pamięci

jc

wb_x7

;jeśli układ nie odpowiada, to błąd i wyjście

mov

A,addr_hi

;wysłanie starszego bajtu adresu słowa w pamięci

call

shout

jc

wb_x7

;jeśli układ nie odpowiada, to błąd i wyjście

mov

A,addr_lo

;wysłanie młodszego bajtu adresu słowa w pamięci

call

shout

jc

wb_x7

;jeśli układ nie odpowiada, to błąd i wyjście

mov

index,#buffer

;załadowanie do zmiennej INDEX adresu bufora w RAM

wb_x6:

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 8/12

background image

http://www.easy-soft.tsnet.pl/

mov

A,@index

;pobierz bajt

call

shout

;wyślij do pamięci 24C64

jc

wb_x7

;jeśli układ nie odpowiada, to błąd i wyjście

inc

index

;następna pozycja w buforze

djnz

count,wb_x6

;następny adres w 24C64

clr

C

;zerowanie flagi C - sygnalizacji błędu

wb_x7:

call

stop

;wysłanie polecenie I2C STOP

wb_x8:

ret

;odczyt jednego bajtu do jednej strony bajtów z pamięci 24C64

;wysyła polecenie Random Read a następnie  Sequential Read

;wywołanie: adres 1-go bajtu w ADDR_HI:ADDR_LO, dane zwracane w BUFFER,

;liczba bajtów w COUNT, zmienna część adresu układu w A

;zwraca CY=1, jeśli magistrala jest zajęta lub pamięć nie odpowiada

;modyfikuje: A, COUNT, INDEX

read_block:

;tryb zapisu w celu ustawienia licznika adresów 24C64

call

start

;wysłanie polecenia I2C START

jc

rb_x5

;przerwa, jeśli magistrala jest zajęta

rl

A

;zmienna część adresu przesuwana jest na poz. bitów 3:1

orl

A,#FIXEDADDR

;dodanie stałej części adresu

mov

index,A

;zapamiętanie kopii adresu urządzenia

clr

ACC.0

;wybór operacji zapisu

call

shout

;wysłanie adresu pamięci

jc

rb_x4

;wyjście, jeśli brak potwierdzenia

mov

A,addr_hi

;wysłanie starszej części adresu słowa

call

shout

jc

rb_x4

;wyjście, jeśli brak potwierdzenia

mov

A,addr_lo

;wysłanie młodszej części adresu słowa

call

shout

jc

rb_x4

;wyjście, jeśli brak potwierdzenia

;zmiana trybu na "odczyt" i odczyt bajtów

call

start

;powtórne wysłanie polecenia I2C START

jc

rb_x4

;wyjście, jeśli brak potwierdzenia

mov

A,index

;odtworzenie adresu pamięci

setb

ACC.0

;kasowanie bitu 0 adresu - odczyt

call

shout

;wysłanie adresu na magistralę I2C

jc

rb_x4

;wyjście, jeśli brak potwierdzenia

mov

index,#buffer

;do zmiennej INDEX wskazanie do bufora

rb_x1:

call

shin

;odbiór bajtu od pamięci

mov

@index,A

;zapamiętanie ich w RAM mikrokontrolera

cjne

count,#1,rb_x2

;skok, jeśli to nie ostatni bajt

call

NAK

;nie wysyłaj potwierdzenia, ostatni bajt

jmp

rb_x3

;wyjście

rb_x2:

call

ACK

;wyślij potwierdzenie

inc

index

;następna pozycja w buforze

djnz

count,rb_x1

;następny bajt w pamięci 24C64

rb_x3:

clr

C

; clear error flag

rb_x4:

call

stop

;wysłanie rozkazu I2C STOP

rb_x5:

ret

;zapis bajtu do pamięci 24C64; wywołanie: adres 1-go bajtu w 

;ADDR_HI:ADDR_LO, dane do zapisu w ZDATA, zmienna część adresu 

;układu pamięci w A, zwraca CY=1, jeśli magistrala jest zajęta lub 

;pamięć nie odpowiada, modyfikuje A

write_byte:

call

start

;wysłanie rozkazu I2C START

jc

wb_y9

;wyjście, jeśli brak potwierdzenia

rl

A

;zmienna część adresu przesuwana jest na poz. bitów 3:1

orl

A,#FIXEDADDR

;dodanie stałej części adresu

clr

ACC.0

;operacja zapisu (b0=0)

call

shout

;wysłanie adresu pamięci

jc

wb_y8

;wyjście, jeśli brak potwierdzenia

mov

A,addr_hi

;wysłanie starszego bajtu adresu słowa

call

shout

jc

wb_y8

;wyjście, jeśli brak potwierdzenia

mov

A,addr_lo

;wysłanie młodszego bajtu adresu słowa

call

shout

jc

wb_y8

;wyjście, jeśli brak potwierdzenia

mov

A,zdata

;pobranie danych z ZDATA do ACC

call

shout

;wysłanie danych do pamięci 24C64

jc

wb_y8

;wyjście, jeśli brak potwierdzenia

clr

C

;kasowanie znacznika błędu

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 9/12

background image

http://www.easy-soft.tsnet.pl/

wb_y8:

call

stop

;wysłanie rozkazu I2C STOP

wb_y9:

ret

;odczyt bajtu spod bieżącego adresu w pamięci 24C64

;wywoływana ze zmienną częścią adresu w A, zwraca bajt w A

;zwraca CY=1, jeśli magistrala jest zajęta lub pamięć nie 

;odpowiada, modyfikuje A

read_current:

call

start

;wysłanie rozkazu I2C START

jc

rc_x5

;wyjście, jeśli brak potwierdzenia

rl

A

;zmienna część adresu przesuwana jest na poz. bitów 3:1

orl

A,#FIXEDADDR

;dodanie stałej części adresu

setb

ACC.0

;operacja odczytu (b0=1)

call

shout

;wysłanie adresu pamięci

jc

rc_x4

;wyjście, jeśli brak potwierdzenia

call

shin

;odbiór bajtu danych

call

NAK

;nie wysyłaj potwierdzenia, koniec operacji

clr

C

;kasowanie flagi sygnalizacji błędu

rc_x4:

call

stop

;wysłanie rozkazu I2C STOP

rc_x5:

ret

;wywyłanie funkcji Read Random (odczyt swobodny)

;wywoływana ze zmienną częścią adresu w A, adresem bajtu w 

;ADDR_HI:ADDR_LO; bajt zwracany w akumulatorze

;zwraca CY=1, jeśli magistrala jest zajęta lub pamięć nie 

;odpowiada

read_random:

push

B

;zapamiętanie stanu rejestru B na stosie

mov

B,A

;zapamiętanie kopii zmiennej części adresu

;tryb zapisu w celu ustawienia licznika adresów 24C64

call

start

;wysłanie rozkazu I2C START

jc

rr_x7

;wyjście, jeśli brak potwierdzenia

rl

A

;zmienna część adresu przesuwana jest na poz. bitów 3:1

orl

A,#FIXEDADDR

;dodanie stałej części adresu

clr

ACC.0

;operacja zapisu (b0=0)

call

shout

;wysłanie adresu pamięci

jc

rr_x6

;wyjście, jeśli brak potwierdzenia

mov

A,addr_hi

;wysłanie starszego bajtu adresu słowa

call

shout

jc

rr_x6

;wyjście, jeśli brak potwierdzenia

mov

a,addr_lo

;wysłanie młodszego bajtu adresu słowa

call

shout

jc

rr_x6

;wyjście, jeśli brak potwierdzenia

;wywołanie funkcji Call Current Address Read

mov

A,B

;odtwórz zmienną część adresu

call

read_current

jmp

rr_x7

;wyjście

rr_x6:

call

stop

;wysłanie rozkazu I2C STOP

rr_x7:

pop

B

;odtworzenie stanu rejestru B

ret

;wysłanie polecenie I2C START (SDA = "1" -> "0" przy SCL = "1")

;powrót z SCL = SDA = 0, zwraca CY = 1, jeśli magistrala jest zajęta

start:

setb

SDA

setb

SCL

;sprawdzenie zajętości magistrali I2C

jnb

SDA,st_x0

;skok, jeśli SDA <> "1"

jnb

SCL,st_x0

;skok, jeśli SCL <> "1"

nop

;czas na ustalenie się linii

clr

SDA

;zmiana stanu SDA (SDA -> "0" przy SCL = "1")

nop

;opóźnienie

nop

nop

clr

SCL

;zmiana stanu SCL (SCL -> "0" przy SDA = "0")

clr

C

;kasowanie flagi sygnalizacji błędu

jmp

st_x1

st_x0:

setb

c

;ustawienie flagi sygnalizacji błędu

st_x1:

ret

;wysłanie rozkazu I2C STOP (SDA = "0" -> "1" przy SCL = "1")

;spodziewane jest SCL = "0", powrór z SDA = SCL = "1"

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 10/12

background image

http://www.easy-soft.tsnet.pl/

stop:

clr

SDA

nop

;czas na ustalenie SDA

setb

SCL

;SCL -> "1" przy SDA = "0"

nop

;czas na ustalenie

nop

nop

setb

SDA

;zmiana SDA -> "1"

ret

;wyprowadzenie bajtu przez SDA w takt SCL (najbardziej znaczący

;bit wyprowadzany jest jako pierwszy); wywoływana z bajtem do 

;wysłania w A, zwraca CY = 1, jeśli magistrala jest zajęta

shout:

push

B

;zapamiętanie stanu rejestru B na stosie

mov

B,#8

;rejestr B jako licznik wysyłanych bitów

sho_x2:

rlc

A

;przesunięcie bajtu w lewo i przeniesienie najstarszego

;bitu dla flagi C

mov

SDA, c

;wyprowadzenie bitu

nop

;czas na ustalenie się wyjścia mikrokontrolera

setb

SCL

;zmiana SCL ___|```

nop

;czas na ustalenie 

clr

SCL

;zmiana SCL ```|___

djnz

B,sho_x2

;następny bit

setb

SDA

;ustawienie SDA = "1" dla odbioru ACK

nop

;czas na ustalenie się pamięci

setb

SCL

;narastające zbocze SCL

nop

;czas na ustalenie 

mov

C,SDA

;odczyt bitu ACK

clr

SCL

;zmiana SCL "1" -> "0"

pop

B

;odtworzenie stanu rejestru B

ret

;odczyt 8 bitów, kompletacja słowa danych (z postaci szeregowej na równoległą)

;jako pierwszy wprowadzany jest najbardziej znaczący bit, bajt zwracany jest w A

shin:

setb

SDA

;SDA jak wejście

push

B

;zapamiętanie stanu rejestru B na stosie

mov

B,#8

;rejestr B jako licznik wysyłanych bitów

shi_x3:

nop

;czas na ustalenie się linii danych

setb

SCL

;narastające zbocze SCL

nop

mov

C,SDA

;odczyt linii danych

rlc

A

;wprowadzenie bitu do akumulatora na najmłodszą pozycję

clr

SCL

;opadające zbocze SCL

djnz

B,shi_x3

;następny bit

pop

B

;odtworzenie stanu rejestru B

ret

;wysłanie potwierdzenia (stan niski linii SDA)

ACK:

clr

SDA

;wysłanie ACK

nop

;czas na ustalenie

setb

SCL

;narastające zbocze sygnału SCL

nop

;czas na ustalenie

clr

SCL

;opadające zbocze SCL

ret

;wysłanie "nie-potwierdzenia" 

NAK:

setb

SDA

;ustawienie NAK

nop

;czas na ustalenie

setb

SCL

;narastające zbocze sygnału SCL

nop

;czas na ustalenie

clr

SCL

;opadające zbocze SCL

ret

END

Listing 1. Funkcje obsługi pamięci 24C64 w języku asembler 8051.

J.Bogusz „Pamięci FRAM w zastosowaniach”

STRONA 11/12


Document Outline