Avtor: mag. Vladimir Mitrović
E-pošta: vmitrovic12@gmail.com
2017_258_51
V preteklem nadaljevanju smo pojasnili koncept in vsebino programskih knjižnic 24C$SE.sub in 24C$SEmini.sub. Če priključimo eno od njih našemu Bascom-AVR programu bodo ukazi iz knjižnice omogočili enostavno delo s serijskim EEPROM-om AT24C32 iz ZS-042 modula in tudi z drugim EEPROM-i iz 24C družine.
Za ilustracijo sem napisal nekaj programskih primerov, ki kažejo princip dela z ukazi iz teh knjižnic. Tukaj bomo analizirali samo dele programa, ki se nanašajo na ukaze iz knjižnic; za popolno razumevanje dela je potrebno pogledati celotne programe.
Programi AT24C32_1.bas in AT24C32mini_1.bas
Namen programa je preverjanje ukazov 24c32$select, 24c$set_address, 24c$write_b, 24c$write_w, 24c$write_l, 24c$$write, 24c$read_b, 24c$read_w, 24c$read_l, 24c$$read in 24c$erase.
Programi so napisani za vezje po shemi prikazani na sliki 9. Na desni strani slike je poenostavljena shema razvojnega sistema MiniPin in zato lahko vezje realiziramo s pomojo MiniPin, razvojnim sistemom MegaPin ali na neki drugi platformi, ki ima pristopne ustrezne priključke mikrokontrolerja. Na levi strani se nahaja shema ZS-042 modula, pravzaprav samo tistega njegovega dela, ki vsebuje EEPROM 24C32. Na isti način se lahko spoji tudi samostojni EEPROM, ki ni sestavni del ZS-042 modula.
Ta vsebina je samo za naročnike
Na začetku programa je potrebno vključiti eno od programskih knjižnic:
$include "24C$SE.sub"
ali
$include "24C$SEmini.sub"
S tem so v programu definirane vse 24c$ spremenljivke in nam postanejo dostopni vsi ukazi iz knjižnice. Sestavni del programa bodo postali samo tisti ukazi, ki jih boste uporabljali. Opomba: obe knjižnici uporabljata novi način definiranja podprograma (Config Submode = New), zato je to treba upoštevati, če se v programu uporabljajo podprogrami iz nekih drugih knjižnic ali lastni podprogrami.
Sledi konfiguracija displeja,
Config Lcdpin = Pin ...
vhodnih pinov (Pind.0 – Pind.4), katerim so dodeljena alternativna imena v skladu s shemo (Pind.0 = Tp1, Pind.1 = Tp2, itd.)
Tp1 Alias Pind.0 Config Tp1 = Input Portd.0 = 1 ...
in I2C vodila, preko katerega mikrokontroler komunicira z EEPROM-om:
Config I2cdelay = 5 Config Sda = Portd.4 'SDA Config Scl = Portd.5 'SCL I2cinit
Po mojih izkušnjah navedeni I2cdelay omogoča največjo hitrost I2C komunikacije (okoli 75 kHz), v primeru ko se uporablja softverska emulacija in 8 MHz clock.
Komunikacijo z EEPROM-om pričnemo z njegovo izbiro:
24c32$select 7 , 0
S tem ukazom smo programu dali vedeti, da želimo komunicirati z EEPROM-om tipa 24C32, katerega naslovni biti so A2 A1 A0 = 111b. Zadnji parameter, 0, vključuje acknowledge polling. To pomeni, da program pred vsakim ukazom pisanja in branja preverja, ali je EEPROM pripravljen oziroma ali še obdeluje predhodni write ukaz in je zato potrebno počakati, da se ta aktivnost konča. Alternativno lahko vpišemo želen čas čakanja:
24c32$select 7 , 5
V tem primeru bi program po vsakem ukazu vpisa v EEPROM počakal 5 ms in nato nadaljeval z delom. Po specifikaciji proizvajalca je 5 ms tipični čas, ki je potreben, da bi neki EEPROM iz družine 24C obdelal zadan ukaz vpisa. Sem pa naletel na EEPROM-e ki to nalogo končajo v dveh, pa tudi tiste, ki potrebujejo 7 ms. Zaradi takšnega “razsipanja” parametrov priporočam, da se opcija 0 (acknowledge polling) uporablja kadar koli je to možno, saj zagotavlja najhitrejše možno nadaljevanje izvršitve programa po izdanem write ukazu, vendar pa med čakanjem povzroči povečani promet na I2C vodilu. Če to zaradi nekega razloga predstavlja problem, uporabite fiksni parameter, ki bo EEPROM-u zagotovil dovolj časa za zaključek vpisa. Če izberete prekratek čas, se posamezni bajti ne bodo vpisali ali izbrisali; predolg čas bo zagotovil siguren vpis, vendar bo upočasnil izvrševanje programa.
Če želite prebrati vsebino neke spominske lokacije EEPROM-a in jo shraniti v spremenljivko, je najprej potrebno izbrati naslov in nato izvesti branje:
Dim Bb As Byte, Ll As Long ... 24c$set_address 0 24c$read_b Bb 24c$set_address 4070 24c$read_l Ll V tem primeru je s spominske lokacije na naslovu 0 prebran en bajt in shranjen v byte spremenljivko Bb, nato so, začenši od spominske lokacije 4070, prebrani štirje bajti in shranjeni v long spremenljivko Ll. Isti princip velja tudi za pisanje: najprej je potrebno postaviti naslov, nato pa vpisati podatek. Med vsakim branjem in pisanjem ukazi avtomatsko povečujejo vrednost naslovnega kazalca za številko vpisanih bajtov. To pomeni, da je nekaj podatkov možno vpisati v EEPROM (ali jih prebrati iz njega) "enega za drugim" brez postavljanja naslova za vsaki novi vpis ali branje:
Dim Ww(8) As Word, I As Byte ... 24c$set_address 2041 For I = 1 To 7 24c$write_w Ww(i) Next 24c$write_w &HFEDC
Tukaj se bo, začenši od spominskega naslova 2041 v EEPROM vpisati prvih 7 word spremenljivk iz Ww niza, nato tudi word konstanta &HFEDC. Pri zaporednih vpisih, kot v predhodnem primeru, prihaja do izraza acknowledge polling opcija, o kateri je že prej bilo govora. Čeprav to ni eksplicitno navedeno zaporedno vpisovanje nastopa vedno, kadar je potrebno vpisati več od enega bajta, enako pa tudi kadar vpisujemo spremenljivko tipa word ali long.
Ukaz 24c$erase bo zbrisal vsebino celotnega EEPROM-a:
24c$erase
Tukaj se v zanki vpisuje vrednost FFh v vse lokacije EEPROM-a. Z namenom, da bi brisanje bilo čim krajše, se uporablja postopek page write, v katerem se v enem koraku vpisuje celotna stran. Pri EEPROM-u 24C32 stran vsebuje 32 bajtov, zato je potrebno napraviti samo 128 vpisov (toliko strani ima 24C32), namesto 4096 (toliko bajtov ima 24C32).
Programi AT24C32_2.bas in AT24C32mini_2.bas
Te programi so tudi napisani za vezje po shemi na sliki 9, njihov namen pa je preverjanje ukazov 24c$read_block in 24c32$write_block. Uporabljamo jih, kadar je potrebno prebrati ali vpisati string, single in druge vrste spremenljivk, ki niso “pokrite” z osnovnimi ukazi. S temi ukazi je tudi možno prebrati iz EEPROM-a ali vpisati v njega blok RAM-a, v katerem so definirane spremenljivke različnih tipov. Predpostavimo da imamo v programu definirane naslednje spremenljivke:
Dim Ss As String * 14 Dim Bb(16) As Byte Dim Ww(8) As Word Dim Ll(8) As Long
Programski del
$notypecheck 24c$set_address 16 24c$write_block ss , 15
bo od spominske lokacije na naslovu16 vpisal vseh 15 bajtov spremenljivke Ss, medtem ko bo programski del
24c$set_address 2041 24c$write_block Bb(1) , 64
od spominske lokacije na naslovu 2041 vpisal vsebino ostalih spremenljivk.
Če želite povrniti vsebino teh spremenljivk iz EEPROM-a, je postopek sledeč:
24c$set_address 16 24c$read_block ss , 15 24c$set_address 2041 24c$read_block Bb(1) , 64
Moramo še pojasniti smisel direktive $notypecheck. Če želimo kopirati blok podatkov z ukazi 24c$read_block in 24c$write_block moramo poslati naslov prve spremenljivke in dolžino bloka. Najenostavnejši način pošiljanja naslova je takšen, da v klicu podprograma navedemo ime spremenljivke, v podprogramu pa uporabimo opcijo byref. Konkretno bi to bilo tako:
24c$read_block ss , 15 ... Sub 24c$read_block(byref 24c$$par1 As Word , Byval 24c$$par2 As Word)
Bascom-AVR med prevajanjem izvaja preverjanje vrst podatkov, ki se pošiljajo podprogramom in bi takšna kombinacija (Ss je string, 24c$$par1 je word) bila proglašena kot napaka. Če pa bi vseeno pisali poseben podprogram za vsak mogoči tip podatka v Bascomu, bi to bilo nepraktično. Direktiva $notypecheck preprečuje preverjanje vrst podatkov in s tem rešuje naš problem. V programu jo je dovolj navesti samo enkrat, pred prvim 24c$read_block ali 24c$write_block ukazom. Če želite zadržati funkcionalnost preverjanja vrste podatkov za druge ukaze, jo vključite ponovno po vsakem izvršenem 24c$read_block in 24c$write_block ukazu:
$notypecheck 24c$write_block ... $typecheck ... $notypecheck 24c$read_block ... $typecheck
V Bascom-AVR obstajajo tudi drugi postopki, s katerimi lahko izvemo naslov spremenljivke, npr. s pomočjo varptr() funkcije. Ta način bi zahteval obstoj word spremenljivke, preko katere bi se naslov začetka bloka podatkov prenesla. Rešitev $notypecheck se mi je zdela enostavnejša in sem jo zato uporabil.
Program AT24Cxx_3.bas
Ta program je napisan za vezje po shemi prikazani na sliki 10, kjer so na I2C vodilu povezani trije serijski EEPROM-i:
24C04 (A2 A1 A0 = 01xb), 24C32 (A2 A1 A0 = 111b) i 24C256 (A2 A1 A0 = 110b).
Če imamo v vezju več kot en EEPROM, moramo poskrbeti, da so njihovi naslovni pini A2 A1 A0 postavljeni na različne naslove. Koncept je takšen, da je v vsakem trenutku možno komunicirati samo z enim od EEPROM-ov, tistim kateremu je poslan zadnji ukaz select. Konkretno, po ukazu:
24c04$select 2 , 0
vsi ostali ukazi iz knjižnice se bodo nanašali samo na ta čip. Če želimo napraviti nekaj s čipom 24C256, ga moramo najprej izbrati:
24c256$select 6 , 0
To “preklapljanje” s čipa na čip je možno ponavljati poljubno-krat; imejte pri tem v mislih to, da vsak novi select ukaz zbriše vse podatke o predhodno izbranem čipu in tudi vrednost naslovnega kazalnika. Če si to vrednost želite zapomniti, jo prepišite iz spremyenljivke 24c$current_address preden izdate novi select ukaz.
Drugi namen programa AT24Cxx_3.bas je preverjanje vpliva parametra, ki vključuje acknowledge polling ali definira trajanje pavze po write ukazu. Ravno s tem programom sem ugotovil, da vpis ene strani v EEPROM XL24C04 traja 7 ms, medtem ko je EEPROM AT24C32 za isto nalogo potreboval samo 2 ms. Podatki se nanašajo na primere, ki sem jih imel na razpolagi in se ne morejo vzeti kot splošno pravilo. Pri vseh čipih so z vklopom acknowledge polling opcije izginili vsi timing problemi vezani na vpis podatkov v EEPROM.
Fotografije testnega vezja s tremi EEPROM-i so prikazane na slikah 11 in 12. Na isti način bi se lahko uporabil tudi neki zmogljivejši mikrokontroler, kot ATmega328P. Postopek prilagoditve programa je opisan v 2. delu (Svet elektronike št. 256) in ga zato tukaj ne bomo ponavljati. Program za ATmega328P zavzema nekaj več spomina od programa za ATtiny4314, in zato bo uporabnikom demo verzije Bascom-AVR priporočljivo uporabiti 24C$SEmini.sub knjižnico, v nekaterih programih se je potrebno pozabavati tudi z optimiziranjem kode, da bi prevedeni program lahko sprogramirali znotraj 4 kB.