Inhoudsopgave:

AVR Assembler Tutorial 1: 5 stappen
AVR Assembler Tutorial 1: 5 stappen

Video: AVR Assembler Tutorial 1: 5 stappen

Video: AVR Assembler Tutorial 1: 5 stappen
Video: AVR Ассемблер. Урок 1. Вводный. AVR Assembler. Lesson 1. Promo. 2024, November
Anonim
AVR-assemblagehandleiding 1
AVR-assemblagehandleiding 1

Ik heb besloten een reeks tutorials te schrijven over het schrijven van assembleertaalprogramma's voor de Atmega328p, de microcontroller die in de Arduino wordt gebruikt. Als mensen geïnteresseerd blijven, zal ik er een per week of zo blijven uitgeven totdat ik geen vrije tijd meer heb of anders stoppen met het lezen ervan.

Ik gebruik Arch linux en ik werk aan een atmega328p-pu-setup op een breadboard. Je kunt het op dezelfde manier doen als ik of je kunt gewoon een arduino op je computer aansluiten en op die manier aan de microcontroller werken.

We zullen programma's schrijven voor de 328p zoals die in de meeste arduino's, maar je moet er rekening mee houden dat dezelfde programma's en technieken ook zullen werken voor alle Atmel-microcontrollers en later (als er interesse is) zullen we werken met een aantal van de andere ook. De details van de microcontroller zijn te vinden in de Atmel datasheets en de Instruction Set Manual. Ik koppel ze aan dit instructable.

Dit is wat je nodig hebt:

1. Een breadboard

2. Een Arduino, of alleen de microcontroller

3. Een computer met Linux

4. De avra-assembler die git gebruikt: git clone https://github.com/Ro5bert/avra.git of als u ubuntu of een op debian gebaseerd systeem gebruikt, typt u gewoon "sudo apt install avra" en u krijgt zowel de avr-assembler en avrdude. ECHTER, als je de nieuwste versie krijgt met github, krijg je ook alle benodigde include-bestanden, met andere woorden, het heeft al de m328Pdef.inc- en tn85def.inc-bestanden.

5. avrdude

De complete set van mijn AVR-assembler-tutorials is hier te vinden:

Stap 1: bouw een testbord

Bouw een testbord
Bouw een testbord

Je kunt gewoon je arduino gebruiken en alles in deze tutorials daarover doen als je wilt. Omdat we het echter hebben over codering in assembleertaal, is onze filosofie inherent om alle randapparatuur weg te halen en rechtstreeks met de microcontroller zelf te communiceren. Dus denk je niet dat het leuker zou zijn om het op die manier te doen?

Voor degenen onder u die het ermee eens zijn, kunt u de microcontroller uit uw Arduino halen en dan beginnen met het bouwen van een "Breadboard Arduino" door de instructies hier te volgen:

Op de foto laat ik mijn opstelling zien die bestaat uit twee zelfstandige Atmega328p's op een groot breadboard (ik wil de vorige tutorial bedraad en geladen op één microcontroller kunnen houden terwijl ik aan de volgende werk). Ik heb de voeding zo ingesteld dat de bovenste rail 9V is en alle andere 5V van de spanningsregelaar. Ik gebruik ook een FT232R breakout board om de chips te programmeren. Ik heb ze gekocht en er zelf bootloaders op gezet, maar als je er net een uit een Arduino haalt dan is het al goed.

Merk op dat als je dit probeert met een ATtiny85, je de Sparkfun Tiny Programmer gewoon hier kunt krijgen: https://www.sparkfun.com/products/11801# en vervolgens gewoon in de USB-poort van je computer steekt. U moet eerst een bootloader op de Attiny85 installeren en de eenvoudigste manier is om gewoon de Arduino IDE te gebruiken. U moet echter op bestand en voorkeuren klikken en vervolgens deze URL voor nieuwe borden toevoegen: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json, wat zal je in staat stellen om de bootloader te installeren (als je ATtiny85 er nog niet een had).

Stap 2: Installeer de Assembler en Avrdude

U kunt nu de assembler en avrdude downloaden en installeren via de links in de eerste stap van deze tutorial. Het is waarschijnlijk dat als je al met Arduino's hebt gewerkt, je avrdude al hebt geïnstalleerd.

Nadat je avra hebt geïnstalleerd, zul je merken dat er een bijbehorende submap is met de naam "sources" en in die map bevinden zich een aantal include-bestanden. Dit zijn alle microcontrollers die u met avra kunt programmeren. U zult meteen merken dat er geen bestand is voor de 328p die we hier gebruiken. Ik heb er een bijgevoegd. Het bestand moet m328Pdef.inc heten en je moet het in de map include plaatsen of waar je maar wilt. We zullen het opnemen in onze assembleertaalprogramma's. Dit alles geeft elk van de registers in de microcontroller-namen uit het gegevensblad, zodat we hun hexadecimale namen niet hoeven te gebruiken. Het bovenstaande include-bestand bevat "pragma-richtlijnen" omdat het is ontworpen voor C- en C++-programmering. Als je moe wordt van het zien van de assembler die klachten "negeren pragma-richtlijn" uitspuugt, ga dan gewoon naar het bestand en verwijder of becommentarieer alle regels die beginnen met #pragma

Oké, nu je je microcontroller klaar hebt, je assembler klaar en je programmeur klaar, kunnen we ons eerste programma schrijven.

Opmerking: als je de ATtiny85 gebruikt in plaats van de ATmega328P, dan heb je een ander include-bestand nodig met de naam tn85def.inc. Ik zal het ook bijvoegen (merk op dat ik het tn85def.inc.txt moest noemen zodat Instructables me zou toestaan het te uploaden.) ECHTER, als je de avra-assembler van github hebt, dan heb je beide bestanden er al bij. Dus ik raad aan om het te krijgen en het zelf te compileren:git clone

Stap 3: Hallo wereld

Het doel van deze eerste tutorial is om het standaard eerste programma te bouwen dat je schrijft wanneer je een nieuwe taal leert of een nieuw elektronicaplatform verkent. "Hallo Wereld!." In ons geval willen we gewoon een assemblerprogramma schrijven, het samenstellen en uploaden naar onze microcontroller. Het programma zorgt ervoor dat een LED gaat branden. Een LED laten "knipperen" zoals ze doen voor het normale Arduino hello world-programma is eigenlijk een veel gecompliceerder programma in assembleertaal en dus zullen we dat nu nog niet doen. We gaan de eenvoudigste "kale botten" code schrijven met minimale onnodige pluisjes.

Sluit eerst een LED van PB5 (zie het pinout-diagram) die op een arduino ook Digital Out 13 wordt genoemd, aan op een weerstand van 220 ohm en vervolgens op GND. D.w.z.

PB5 -- LED -- R (220 ohm) -- GND

Nu het programma schrijven. Open uw favoriete teksteditor en maak een bestand met de naam "hello.asm"

;hallo.asm

; schakelt een LED in die is aangesloten op PB5 (digital out 13).include "./m328Pdef.inc" ldi r16, 0b00100000 out DDRB, r16 out PortB, r16 Start: rjmp Start

Bovenstaande is de code. We zullen het zo regel voor regel doornemen, maar laten we er eerst voor zorgen dat het op uw apparaat werkt.

Nadat u het bestand hebt gemaakt, stelt u het als volgt samen in een terminal:

avra hallo.asm

dit zal je code samenstellen en een bestand maken met de naam hello.hex dat we als volgt kunnen uploaden:

avrdude -p m328p -c stk500v1 -b 57600 -P /dev/ttyUSB0 -U flash:w:hello.hex

als je een breadboard-arduino gebruikt, moet je op de resetknop op de breadboard-arduino drukken net voordat je de bovenstaande opdracht uitvoert. Merk op dat je misschien ook een sudo vooraan moet toevoegen of het als root moet uitvoeren. Merk ook op dat je op sommige Arduino's (zoals de Arduino UNO) waarschijnlijk de bitrate moet veranderen in -b 115200 en de poort -P /dev/ttyACM0 (als je een foutmelding krijgt van avrdude over een ongeldige apparaathandtekening, voeg dan gewoon een - F naar het commando)

Als alles naar behoren heeft gewerkt, gaat er nu een LED branden … "Hello World!"

Als u de ATtiny85 gebruikt, is het avrdude-commando:

avrdude -p attiny85 -c usbtiny -U flash:w:hallo.hex

Stap 4: Hello.asm regel voor regel

Om deze inleidende tutorial af te ronden, zullen we regel voor regel het hello.asm-programma doornemen om te zien hoe het werkt.

;hallo.asm

; gaat een LED aan die is aangesloten op PB5 (digital out 13)

Alles na een puntkomma wordt genegeerd door de assembler en daarom zijn deze eerste twee regels gewoon "opmerkingen" die uitleggen wat het programma doet.

.inclusief "./m328Pdef.inc"

Deze regel vertelt de assembler om het m328Pdef.inc-bestand op te nemen dat u hebt gedownload. Misschien wilt u dit in een map met vergelijkbare include-bestanden plaatsen en vervolgens de bovenstaande regel wijzigen om ernaar te verwijzen.

ldi r16, 0b00100000

ldi staat voor "load instant" en vertelt de assembler om een werkregister te nemen, in dit geval r16, en er een binair getal in te laden, in dit geval 0b00100000. De 0b ervoor zegt dat ons getal binair is. Als we hadden gewild, hadden we een andere basis kunnen kiezen, zoals hexadecimaal. In dat geval zou ons getal 0x20 zijn geweest, wat hexadecimaal is voor 0b00100000. Of we hadden 32 kunnen gebruiken, wat 10 decimaal is voor hetzelfde getal.

Oefening 1: Probeer het getal in de regel hierboven te veranderen in hexadecimaal en vervolgens in decimaal in uw code en controleer of het in elk geval nog steeds werkt.

Het gebruik van binair is echter het eenvoudigst vanwege de manier waarop poorten en registers werken. We zullen de poorten en registers van de atmega328p in meer detail bespreken in toekomstige tutorials, maar voor nu zal ik alleen zeggen dat we r16 gebruiken als ons "werkregister", wat betekent dat we het gewoon gaan gebruiken als een variabele die we opslaan getallen in. Een "register" is een set van 8 bits. Dit betekent 8 spots die ofwel 0 of 1 kunnen zijn ('uit' of 'aan'). Wanneer we het binaire getal 0b00100000 in het register laden met behulp van de bovenstaande regel, hebben we dat nummer eenvoudigweg opgeslagen in het register r16.

uit DDRB, r16

Deze regel vertelt de compiler om de inhoud van het register r16 naar het DDRB-register te kopiëren. DDRB staat voor "Data Direction Register B" en stelt de "pinnen" op PortB in. Op de pinout-kaart voor de 328p kun je zien dat er 8 pinnen zijn met het label PB0, PB1, …, PB7. Deze pinnen vertegenwoordigen de "bits" van "PortB" en wanneer we het binaire getal 00100000 in het DDRB-register laden, zeggen we dat we willen dat PB0, PB1, PB2, PB3, PB4, PB6 en PB7 worden ingesteld als INPUT-pinnen omdat ze 0's erin, en PB5 is ingesteld als een OUTPUT-pin omdat we op die plek een 1 hebben geplaatst.

uit PoortB, r16

Nu we de richtingen van de pinnen hebben vastgesteld, kunnen we nu de spanningen erop instellen. De bovenstaande regel kopieert hetzelfde binaire getal van ons opslagregister r16 naar PortB. Hiermee worden alle pinnen op 0 volt gezet, behalve pin PB5 op HOOG, wat 5 volt is.

Oefening 2: Neem een digitale multimeter, steek de zwarte draad in aarde (GND) en test vervolgens elk van de pinnen PB0 tot en met PB7 met de rode draad. Zijn de spanningen op elk van de pinnen precies die overeenkomen met het plaatsen van 0b00100000 in PortB? Als er mensen zijn die dat niet zijn, waarom denk je dat dat wel het geval is? (zie de pinnenkaart)

Begin:

rjmp Start

Ten slotte is de eerste regel hierboven een "label" dat een plek in de code markeert. In dit geval label je die plek als "Start". Op de tweede regel staat 'relatieve sprong naar het label Start'. Het netto resultaat is dat de computer in een oneindige lus wordt geplaatst die gewoon terug blijft fietsen naar Start. We hebben dit nodig omdat we het programma niet zomaar kunnen laten eindigen, of van een klif kunnen vallen, het programma moet gewoon doorgaan zodat het licht blijft branden.

Oefening 3: Verwijder de bovenstaande twee regels uit je code zodat het programma van een klif valt. Wat gebeurt er? Je zou iets moeten zien dat lijkt op het traditionele "knipper"-programma dat door Arduino wordt gebruikt als hun "hallo wereld!". Waarom denk je dat het zo werkt? (Bedenk wat er moet gebeuren als het programma van een klif valt…)

Stap 5: Conclusie

Als je zo ver bent gekomen, gefeliciteerd! U kunt nu assembly-code schrijven, samenstellen en op uw microcontroller laden.

In deze tutorial heb je geleerd hoe je de volgende commando's gebruikt:

ldi hregister, nummer laadt een nummer (0-255) in een bovenste halve register (16-31)

out ioregister, register kopieert een nummer van een werkregister naar een I/O-register

rjmp label springt naar de regel van het programma gelabeld met "label" (die niet verder dan 204 instructies verwijderd kan zijn -- d.w.z. relatieve sprong)

Nu deze basis uit de weg is, kunnen we doorgaan met het schrijven van interessantere code en interessantere circuits en apparaten zonder de mechanica van compileren en uploaden te hoeven bespreken.

Ik hoop dat je genoten hebt van deze inleidende tutorial. In de volgende tutorial zullen we nog een circuitcomponent (een knop) toevoegen en onze code uitbreiden met invoerpoorten en beslissingen.

Aanbevolen: