AVR Assembler Tutorial 4 (6 / 9 stap)

Stap 6: Pointers en opzoektabellen


Om het even welk van u die hebben ervaring met C of C++ al hebben ervaring met pointers. We zullen het zelfde ding hier in het kader van "opzoektabellen" gebruiken.

Opzoektabellen zijn een andere manier van het compactifying van onze code om het kortere, meer elegant en gemakkelijker te begrijpen te maken.

Laat eerst de code schrijven en dan zullen we uitleggen wat er gebeurt. Eerst, op de top van ons programma zal er een sectie met het label "nummers:" gevolgd door ".db" assembler richtlijnen. Deze richtlijnen "Definieer bytes" en wat ze doen is dat ze plaatsen die bytes opeenvolgend in een bepaalde sectie van "Programmageheugen" gedefinieerd door de label-nummers. Dus wanneer is de hexadecimale code in de microcontroller geladen, een bepaald segment van het flitsgeheugen dat alle van de programma-instructies worden opgeslagen zal bevatten deze bytes één na de andere in volgorde.

Vervolgens kunnen wij eigenlijk deze nummers krijgen, wanneer we willen dat ze omdat ze altijd gevestigd in bepaalde geheugenlocaties opgegeven programma worden zal. Herinner me hoe we interrupts behandeld? We een instructie aan precies 0x0020 in het programmageheugen geplaatst. We wisten dat als er een timer overflow interrupt is opgetreden voor de cpu zou die exacte locatie controleren en welke commando we er zetten. Opzoektabellen werken goed in een zeer gelijkaardige manier.

We gaan opnieuw schrijven onze "dobbelstenen:" label subroutine, die is enerzijds dat de microcontroller welke pinnen vertelt om welk nummer op een sterven, zodat in plaats van een lange en lelijk sectie van code, kan het gebruik van een lus en dingen eenvoudiger doen inschakelen. Hier is de nieuwe code:

U ziet dat het veel korter is. In feite, wanneer je merkt dat je is herhalende dezelfde set instructies over en binnen een subroutine en het enige ding anders elke keer dat een bepaald aantal, dat is een perfecte tijd verschilt te gebruiken van een opzoektabel. In de gevallen waar zou u een "lus" of een "schakelaar-zaak" routine in C of een andere taal, dat is een goed moment om het gebruik van een opzoektabel in assembler.

Opzoektabellen hebben een reputatie voor het wordt ingewikkeld maar ik denk niet dat het is verdiend. Ik zal proberen uit te leggen op een eenvoudige manier hier.

Laten we beginnen met de atmega328p geheugen kaart. Er zijn drie verschillende soorten geheugen beschikbaar voor het opslaan van spullen. Het "programmageheugen" dat ons programma slaat, de "SRAM datageheugen", die alle van de registers die we als het algemene doel werken registers, de input-output-poorten en alle van de registers die we om de knevel bits en controle gebruiken gebruiken, de manier waarop dingen zijn gedaan en ten slotte het "EEPROM"-geheugen, dat wij in een latere tutorial introduceren zullen bevat (als ik laatste dat lang) en wordt gebruikt voor het opslaan van informatie die niet verdwijnen zal wanneer wij zwenking uit de macht. Erg handig als u een spel maakt en u wilt bewaren somebodies score tot de volgende keer dat ze spelen!

We weten dat elke byte van een bepaalde soort geheugen een adres heeft. Bijvoorbeeld, de eerste byte code wij voeren 0x0000 bedraagt en de timer overflow interrupt handler is op 0x0020, enz. U zult opmerken dat sinds we meer dan 256 bytes van het geheugen in onze programmageheugen ruimte hebben wij niet gewoon adressen 0x00 tot 0xFF gebruiken kunnen. In feite, hebben we 32k flash-geheugen in de geheugenruimte van het programma. Dit betekent dat we moeten adressen uit 0x0000 tot 0x7FFF.

Nu, stel dat we willen om te lezen wat er op een specifiek adres in het geheugen? Bijvoorbeeld, wanneer de cpu een overflow interrupt krijgt het gaat naar 0x0020 en voert de instructie die we daar geplaatst. Wat als we willen plaatsen instructies of gegevens of wat dan ook op een specifiek adres in programmageheugen en vervolgens dat te gebruiken in ons programma? Wij kunnen, behalve dat ons algemene doel registreert kan alleen houden 8 bits (1 byte) tussen 0x00 en 0xFF, en zoals we hebben gezien, een adres heeft 2 bytes te noteren (tussen 0x0000 en 0x7FFF). Er is dus niet genoeg ruimte in een algemene doel-register (d.w.z. een variabele zoals r16) te houden een programma geheugenadres. We kunnen niet "ldi r16, 0b0000000000000010" bijvoorbeeld zeggen aangezien R16 is niet groot genoeg. Dus als we hebben geen manier om het volledige adres hoe op te slaan kunnen gaan we er tijdens het programma? We gewoon pak de telefoon, bel de cpu, en zeggen "kunt u gaan en uitvoeren wat we opgeslagen op 0x2a7f gelieve" je dat adres in een r16 of iets en dan "mov" moet hebben om het of "uit" het vanaf daar.

Dus is hier wat de ATmel mensen hebben gedaan om op te lossen van dit dilemma. Ze hebben dual beoogde doeleinden een paar van onze algemene doel-registers. In het bijzonder, als je kijkt naar de tabel 7-2 op pagina 12 van het gegevensblad, kunt u zien hoe de algemene doel-registers worden georganiseerd. De registers r26, r27, r28, r29, r30 en r31 kan ook worden gecombineerd tot paren genaamd X, Y en Z. Dus dat X r26 en r27 samen is, Y is r28 en r29 samen, en Z is r30 en r31 samen. Op die manier als we Z bijvoorbeeld, de eerste helft van het nemen r30 is en de tweede helft van het r31. Dus als we willen slaan een programma geheugenadres slaan we de helft van het net in r30 en de andere helft van het in r31 en vervolgens vertellen we de cpu Z opzoeken als we willen praten over het hele ding samen. Zij hebben uitgevoerd twee instructies die dit doen. De eerste is spm, wat voor "Winkel programmageheugen staat" en de andere is lpm wat voor "Load programmageheugen staat". Dus nu als we krijgen wat ooit instructie of data wordt opgeslagen op geheugenadres 0x24c8 bijvoorbeeld willen, zouden we dat adres in r30 en r31 en vervolgens wanneer we willen krijgen van de gegevens die we zouden gewoon lpm het aan een variabele door te doen

die zal gaan naar geheugenadres Z, welke gegevens wij er zetten nemen, en plak het in r16. Het koele ding over dit is dat als we er 1 bij tot het gebruik van Z optellen

dan zal Z nu "wijs" het volgende geheugenadres na de eerste. Dus dat als we houden een hele lijst met getallen in het geheugen een na de andere die wij hen door oplopende Z kunt doorlopen.

Hoe gebruiken we dit in ons programma?

Nou, aangezien elk getal op de dobbelsteen wordt weergegeven door het op en uitschakelen van verschillende havens zoals PC2 en PB5 slaan we gewoon het nummer dat voor elk getal op de dobbelsteen doet. Bijvoorbeeld als we "out" 0b11010010 te PortC PC0 wordt ingesteld op 0, 1, PB1 enz en schakelt de bijbehorende LED's om ons te geven onze getal op de dobbelsteen. In dit geval de nummer 4.

Dus we een 'opzoektabel gebruiken zullen' genaamd "nummers:" opslaan van al deze verschillende sterven-configuraties te vereenvoudigen van onze code.

Ik denk dat als je de bovenstaande code leest, en de verschillende aanwijzingen in de handleiding opzoeken, kunt u gemakkelijk uitzoeken hoe het werkt. Het enige vreemde deel is de eerste bit waar we de aanwijzer Z initialiseren.

Wat dit doet is geïnitialiseerd de aanwijzer Z te wijzen op onze lijst met het label "nummers". De reden voor de 2 keer op de voorgrond is dat we willen dat het adres van "getallen" verschoven naar de linker één spatie (thats wat keer door twee doet naar binaire getallen). Dit laat de rechtse bit (de minst significante bits) die vervolgens wordt gebruikt om te beslissen welke byte van programmageheugen verwijzen wij naar gratis. Dit komt omdat programmageheugen 2 bytes (16 bits) breed. Dus bijvoorbeeld, in onze opzoektabel hebben we de eerste twee nummers als
.db 0b01111111, 0b11011110

Aangezien de ruimte programmageheugen 16 bits breed is beide van deze nummers zullen eigenlijk zitten op hetzelfde programmageheugen adres dus de manier waarop we grijpen de eerste of de tweede is waarom we moeten de "times door 2" of linker shift van de bits. Wanneer de "minst significante bit" van Z een 0 is het zal wijzen naar de eerste van onze lijst: 0b01111111, en bij het minste significante beetje van Z is een het naar de tweede men van onze lijst verwijzen zal 1: 0b11011110.

Zoals u zien kunt, verandert het toevoegen van 1 tot en met Z het minst significante bit van een 0 naar een 1 en vervolgens toe te voegen 1 tot en met Z verhoogt opnieuw het programma geheugenadres en de LSB gaat terug naar nul. U ziet dus dat het werkt groot voor het plukken van onze volledige lijst met opgeslagen nummers één tegelijk door simpelweg verhogen van Z.

Bericht dat wanneer we verschuiven het adres van "getallen" links door te vermenigvuldigen met 2 tot het vrijmaken van de minst significante bits gebruiken voor het selecteren van de eerste of tweede byte op dat adres opgeslagen die we verliezen de "meest significante bit" van het adres. Dit betekent dat we alleen onze lookup tabelgegevens kunnen opslaan in adressen waar de meest significante bit niet belangrijk - dat wil zeggen onze benoemde gegevens zullen allemaal de zelfde meest significante bit. Dit betekent dat ons adres is effectief 15 bits lang. 2 ^ 15 is 32768 verschillende adressen beschikbaar voor onze opgeslagen gegevens. We gaan om te kijken naar dit meer in detail in de volgende tutorial dus maak je geen zorgen als het is een beetje verwarrend op dit punt.

Nu weet u hoe opzoektabellen en de X, Y, en Z pointers gebruiken om uw schrijven van de code te vereenvoudigen.

Laten we geven nu het volledige programma met deze vernieuwingen opgenomen.

Gerelateerde Artikelen

AVR Assembler Tutorial 2

AVR Assembler Tutorial 2

Deze tutorial is een voortzetting van het "AVR Assembler Tutorial 1"Als je niet hebt doorlopen Tutorial 1 moet je nu stoppen en dat men eerst doen.In deze tutorial zullen we onze studie van assembly language programmering van de atmega328p in de
AVR Assembler Tutorial 11

AVR Assembler Tutorial 11

Welkom bij Tutorial 11!In deze korte tutorial, zijn we eindelijk het eerste deel van onze laatste project bouwen.Het eerste wat dat u moet doen is gaat u naar de allerlaatste stap van deze tutorial en Bekijk de video. Dan kom hier terug. [onderbreken
AVR Assembler Tutorial 1

AVR Assembler Tutorial 1

Ik heb besloten om een serie tutorials over hoe te schrijven van assembler programma's voor de Atmega328p die het gebruikt in de Arduino microcontroller is schrijven. Als mensen geïnteresseerd blijven blijft ik stak een een week of zo totdat ik oprak
AVR Assembler Tutorial 6

AVR Assembler Tutorial 6

Welkom bij Tutorial 6!Today's tutorial zullen kort waar zullen we het ontwikkelen van een eenvoudige methode om gegevens tussen een atmega328p en een andere met twee poorten verbinden hen te delen. Wij zullen vervolgens nemen de dobbelstenen rol van
AVR Assembler Tutorial 8

AVR Assembler Tutorial 8

Welkom bij Tutorial 8!In deze korte tutorial gaan we een beetje een afleiding van de invoering van nieuwe aspecten van assembly language programmering te laten zien hoe onze prototyping componenten verplaatsen naar een aparte "gedrukt" printplaa
AVR Assembler Tutorial 9

AVR Assembler Tutorial 9

Welkom bij Tutorial 9.Vandaag zullen wij tonen hoe de controle van zowel een 7-segment display en een 4-cijferige weergave met behulp van onze ATmega328P en AVR assembler code. In de loop doen die we nemen van omleidingen moeten zal op how to use van
AVR Assembler Tutorial 7

AVR Assembler Tutorial 7

Welkom bij Tutorial 7!Vandaag gaan we naar eerste show hoe opruimen van een toetsenbord, en vervolgens laten zien hoe de analoge input poorten gebruiken om te communiceren met het toetsenblok.We zullen dit doen met behulp van interrupts en een enkele
AVR Assembler Tutorial 10

AVR Assembler Tutorial 10

Welkom bij Tutorial 10!Sorry dat het zo lang duurde om deze volgende aflevering eruit maar dit is een behoorlijk hectische tijd van het jaar. In ieder geval, is hier het!We hebben een lange weg afgelegd en u bent waarschijnlijk al bekwaam genoeg is o
AVR Assembler Tutorial 5

AVR Assembler Tutorial 5

Vandaag gaan we nemen een kijkje op de verschillende geheugenlocaties in de Atmega328p microcontroller en zien als we beter begrijpen kunnen hoe de dingen worden opgeslagen, waar ze worden opgeslagen en hoe de pointers en opzoektabellen werken.De tut
AVR Assembler Tutorial 3

AVR Assembler Tutorial 3

Welkom op tutorial nummer 3!Voordat we beginnen wil ik een filosofische opmerking maken. Wees niet bang om te experimenteren met de circuits en de code die we proberen op te in deze tutorials bouwen. Draden rond wijzigen, nieuwe onderdelen toe te voe
Een geavanceerde benadering van programmering van Arduino & AVR

Een geavanceerde benadering van programmering van Arduino & AVR

Dit instructable is een must read voor iedereen die vertrouwd is met core AVR chips en Arduino.Nou, om meer specifieke, bij het lezen van de instructable, zal u zitten kundig voor:1) weten het juiste verschil tussen AVR en Arduino.2) programmering Ar
Programmeerbare LED

Programmeerbare LED

geïnspireerd door diverse LED Throwies, knipperende LEDs en soortgelijke instructables ik wilde doen van mijn versie van een LED aangestuurd door een microcontroller.Het idee is om de LED knipperende reeks Herprogrammeerbare. Deze herprogrammering ka
De generator van willekeurige golfvorm, voor ~ 20$

De generator van willekeurige golfvorm, voor ~ 20$

een willekeurige golfvorm generator (AWG) is een nuttige maar vaak duur stuk van testapparatuur (ebay voor lacht). Gebruiken om te bepalen component frequentiebereik, genereren van vervoerder signalen, als een LCR-meter als u een bereik, tune resonan
Star Trek deurbel Hack

Star Trek deurbel Hack

Ik heb altijd al een fan van de Star Treks en als zodanig ik was erg opgewonden toen mijn kamergenoot bracht het huis van een originele serie stijl Star Trek comm panel. Ik had nog nooit gezien een van deze, maar een snelle zoektocht nam ons mee naar