Hoe lees je data uit het interne Flash geheugen van de ATtiny2313 ?
Deze AVR heeft 2k (2048 bytes) Flash geheugen. Flash geheugen kan 1000 keer gegarandeerd overschreven worden (waarschijnlijk wel 10 keer meer) Dit geheugen kan worden gebruikt voor twee doeleinden, programma opslag of data opslag, of beide. Als je alle ASCII karakters wilt opslaan (Ik neem de ASCII set van de SLO2016), dat zijn 0 t/m 127 = 128 karakters, heb je 128 x 5 bytes = 640 bytes (= 320 woorden) Flash geheugen nodig. Hier een aantal karakters op de dotmatrix display:

Hier aantal van de 128 symbolen van de ASCII set uit het Flash geheugen gelezen.
Een AVR is niet een extreem gecompliceerde microcontroller, zet de tabel simpelweg aan het einde van de routines, op deze manier:
.CSEG
ASCII:
.db 0b01111111,0b00001001 ;char0
.db 0b00011001,0b00101001 ;char0
.db 0b01000110,'#' ;char0
Dit is een ASCII teken (de R) Het Flash geheugen is 16bit breed, ik heb de tabel op deze wijze ingedeeld, zodat je goed de rijen-data kan zien. Het '#' teken is het eind symbool, in de routine doe je een vergelijking:
cpi data, '#'
Als het dit teken tegen komt kun je het laten vertakken of verspringen naar een andere routine, of terug de hoofdlus in, of wat dan ook. Of je kan een eind label aan het einde van de ASCII tabel plaatsen, op deze wijze:
.db 0b01000110,0b00110010
end_ASCII:
Nu vraag je je af, hoe kun je door het Flash geheugen heen lopen ? Eerst moet je het initialiseren (gereed maken), gebruik deze twee regels assembleer code
ldi ZL, LOW(ASCII*2) ;zet Lage aanwijzer begin tabel
ldi ZH, HIGH(ASCII*2) ;zet Hoge aanwijzer begin tabel
Je ziet duidelijk dat de tabel in twee gedeeltes is opgeplitst, een Lage byte en een Hoge byte (1 woord = 2 bytes) Nu kun je d.m.v. een instruktie genaamd 'lpm' (load program memory = laadt vanuit het programma geheugen) data lezen uit het interne Flash geheugen van de AVR, het uitlezen begint meteen na de label 'ASCII:' De data van deze tabel word opgeslagen in r0 (eerste register van de AT90S2313), 'lpm' doet dit. Als het eenmaal in r0 zit, kun je het gebruiken in je programma, je kan deze data bijv. vervolgens op PORTB zetten, dat doe je dus zo:
lpm ;nu is de data in r0
out PORTB, data ;nu staat de data op de uitgang pinnen van PORTB
Vergeet niet 'data' te defineren, op deze wijze:
.def data = r0
Nu vraag je je nog steeds af, hoe kan ik de volgende byte ophalen vanuit het Flash geheugen ? Je kan bijv. dit doen:
inc ZL ;verhoog Lage aanwijzer
Deze regel veroorzaakt dat de opvolgende byte zal worden aangewezen. Het is niet nodig om het geheugen te organiseren, zet de tabel simpelweg onder je programma code. Als het programma groter word, word de tabel vanzelf opgeschoven door de assembler. De assembler zal een foutmelding geven als het einde van het geheugen zal worden bereikt. Met deze truc moet je wel oppassen, de tabel kan niet te lang worden, omdat als de lage byte-aanwijzer (ZL) continu blijft ophogen, zal de hoge byte-aanwijzer (ZH) de hele tijd hetzelfde blijven, en dus kom je in de problemen. Gebruik liever deze regel:
adiw ZL, 1 ;verhoog aanwijzers
Stel je begint op adres 0x02FA (02 = hoge byte; ZH, FA = lage byte; ZL), als je dan 0x02FF bereikt, zou de aanwijzer moeten gaan naar 0x0300, maar als je alleen ZL gebruikt zal de aanwijzer terug wijze naar 0x0200 inplaats van 0x0300! Hier een voorbeeld programmaatje, die twee LED's om en om laat knipperen (als het '#' symbool word verplaatst zal het een looplichtje worden van 8 LED's) vanuit het geheugen. Hier de SLO2016 ASCII set die ik ga gebruiken :)

De tabel bevat 128 karakters (128 x 5 bytes x 8 bits = 5120 bits totaal)
Met de 128 interne EEPROM bytes van de AT90S2313 kun je maximaal 128 karakters in zetten, er kan dus niet erg veel in worden opgeslagen, maar genoeg voor een klein stukje tekst of berichtje, of aantal prijzen voor een artikel, of valuta bijv. Het getal 65 (0x41) opgeslagen in de EEPROM zal de 'A' laten verschijnen. De rest van het flash geheugen kan bijv. worden gebruikt om speciale karakters in op te slaan of aantal standaard woorden, maak een tabel erbij, deze woorden vereenvoudigen het maken van zinnen.
Hoe lees/schrijf je data van het interne SRAM geheugen van de AT90S2313 ?
Ten eerste, RAM = Random Access Memory, S betekend Statisch. Er zijn twee mogelijkheden. Direkt lezen/schrijven, of indirekt d.m.v. zogeheten Y-aanwijzers (YL en YH) Onthoudt dat de data in SRAM verloren gaat wanneer je de voedingspanning van de ATtiny2313 afhaald. In dit voorbeeld de indirekte methode. Het SRAM gebied van de ATtiny2313 start op locatie $60 = 0x0060 = 0x60, defineer dit getal eerst:
.equ sram = 0x60
De volgende stap zijn Y-aanwijzers (zet ze klaar voor gebruik):
ldi YL, low(SRAM) ;zet Lage geheugen aanwijzer
ldi YH, high(SRAM) ;zet Hoge geheugen aanwijzer
Nu staan deze Y-aanwijzers op SRAM lokatie 0x60 (begin SRAM) Hoe kun je data opslaan in een SRAM lokatie ? Dit is heel eenvoudig! Stel je wilt huidige data opslaan (een byte) in de eerste SRAM lokatie, doe dan dit:
st Y, temp ;sla data op in SRAM
Nu zit de data van 'temp' opgeslagen op de eerste plek in SRAM, omdat de Y-aanwijzers op die plek gezet waren. Hoe kun je dezelfde data opslaan in de tweede SRAM geheugen-lokatie ? Verhoog simpelweg de Y-aanwijzers, of nog simpeler, gebruik het '+' teken, op deze manier:
st Y+, temp ;sla data op in volgende SRAM lokatie
Het '+' teken betekend, verplaats Y een positie omhoog, als je omlaag wilt gaan gebruik dan het '-' teken, maar voor de Y:
st -Y, temp ;sla data op in SRAM een lokatie lager
Nu kun je de Y-aanwijzers omhoog- of omlaag zetten. Hoe lees je de data terug in een register vanuit de SRAM ? Gebruik de instructie LD (laden):
ld temp, Y ;laadt gegevens vanuit SRAM
Je kan weer gebruik maken van de tekens '+' or '-' . Wat ook kan gebruikt worden zijn twee andere instrukties STD en LDD (indirekt schrijven/lezen), met deze twee instrukties kun je heel simpel data lezen of schrijven naar of van elke lokatie zonder eerst de Y-aanwijzers van positie te hoeven te verzetten. De Y-aanwijzers komen weer terug op hun laats ingestelde positie. Hier een voorbeeld:
ldd temp, Y+1 ;lees Y+1 in temp
std Y+0, temp ;schrijf temp in Y+0
Y+1 betekend; lees/schrijf een lokatie hoger van/naar SRAM, je kan ook namen gebruiken i.p.v. getallen:
.equ waarde = 6
std Y+waarde, data ;schrijf gegevens in Y+waarde (Y+6)
Verander de positie van de Y-aanwijzers met:
adiw YL, 1 ;verplaats Y-aanwijzers een lokatie hoger
of
sbiw YL, 1 ;verplaats Y-aanwijzers een lokatie lager
Op de volgende pagina's vind je informatie over het aftasten van de Rijen van dit LED loopkrant projekt....
[terug naar boven]