AVR Assembler handledning 5 (4 / 8 steg)

Steg 4: En annan titta på pekare och uppslagstabeller



Låt oss nu se om vi kan använda våra analyzer för att få en bättre uppfattning om hur dessa X, Y och Z pekare och uppslagstabeller fungerar. Jag inser att vår diskussion i sista handledningen kan ha varit lite förvirrande för nykomlingen. Jag tror att detta kommer att göra det allt mer klart.

Låt oss börja med att ändra vår kod enligt följande:

;************************************
; Skrivet av: 1o_o7
; datum: < 2014|11|03 >
; version: 1.0
; filen sparas som: analyzer2.asm
; för AVR: atmega328p
; klockfrekvens: 16MHz
;************************************

; Programmera funcion:---
; analyserar de bitarna lagras i ett register
;---------------------------------------

.nolist
.include ". / m328Pdef.inc"
.lista

.def temp = r16

.org 0x0000
rjmp Init

nummer:
DB 0b01111111, 0b11011110, 0b01011110, 0b11010010
DB 0b01010010, 0b11000000

Init:
ser temp
ut DDRB, temp
ut DDRC, temp
Färgtemp
ut PortB, temp
ut PortC, temp

viktigaste:
LDI ZH, high(2*numbers); ZH är den höga byten i adressen till nummer
LDI ZL, low(2*numbers); ZL är den låga byten i adressen till nummer
MOV r20, r30
rcall analysera
rjmp huvudsakliga

analysera:
Färgtemp
ut portb, temp
ut portc, temp
sbrc r20, 7
SBI portb, 1
sbrc r20, 6
SBI portb, 2
sbrc r20, 5
SBI portb, 3
sbrc r20, 4
SBI portb, 4
sbrc r20, 3
SBI portc, 1
sbrc r20, 2
SBI portc, 2
sbrc r20, 1
SBI portc, 3
sbrc r20, 0
SBI portc, 4
ret

Vi har helt enkelt lagt till en uppslagstabell i toppen (som är exakt samma som vi använde i vår dice program för handledning 4) och sedan vi lagt raderna ZL och ZH i vår Main rutin att initiera Z pekaren.

Vi sedan ladda r30 i våra analyzer register r20 och analysera den på vår styrelse. Du bör göra detta. Du ska hitta det r30 innehåller 0b00000010. Nu gör samma för r31 och du kommer att få 0b00000000.

Adressen till "nummer" är 0x0001 som i binär är 0b0000000000000001 så

LDI ZH, high(2*numbers)

innebär exakt samma som

LDI r31, high(0b0000000000000010)

som är

LDI r31, 0b00000000

På samma sätt

LDI ZL, low(2*numbers)

innebär exakt samma som

LDI r30, low(0b0000000000000010)

som är

LDI r30, 0b00000010

Minns att r30 och r31 kombinera tillsammans göra Z.

Prova detta:

viktigaste:
LDI ZH, high(2*numbers)
LDI ZL, low(2*numbers)
MOV r20, ZL
rcall analysera
rjmp huvudsakliga

Vad händer nu om vi tittar på Z? Tja kan prova det:

viktigaste:
LDI ZH, high(2*numbers)
LDI ZL, low(2*numbers)
LPM r20, Z
rcall analysera
rjmp huvudsakliga

Observera att använda Z, måste vi kommandot LPM. Detta kommer att ladda oavsett data i sitter i adressen som pekas ut av Z. Adressen pekar Z hittas genom att börja med vad som finns i r31 r30, som är 0b0000000000000010 och sedan flytta det tillbaka igen till höger för att få 0b0000000000000001. Så prova det och se vad du får... tjusig rätt? Du får 0b01111111 vilket är precis vad vi lagrade på den adressen. Låt oss fortsätta att försöka göra detta mer uppenbart. Låt oss göra följande:

viktigaste:
LDI ZH, high(2*numbers)
LDI ZL, low(2*numbers)
adiw ZH:ZL, 1
MOV r20, ZL
rcall analysera
rjmp huvudsakliga

Du ser vi lagt 1 till ZH:ZL vilket gör ZL = 0b00000011. Om du bytt ZL i ovanstående med r30 skulle du få exakt samma sak. De är olika namn för samma nummer. Om istället för att använda "adiw ZH:ZL" i ovanstående du använt "inc ZL" eller ens "inc r30" skulle du få samma sak igen. Instruktion adiw betyder "Lägg omedelbart till word" och ett "ord" är 2 byte eller 16 bitar. Så du måste ge det två 8-bitars register, lägger ZH:ZL, eller ekvivalent r31:r30 och det k till denna. I vårt exempel över k är 1.

Låt oss lägga till 1 r30 och sedan se var Z pekar:

viktigaste:
LDI ZH, high(2*numbers)
LDI ZL, low(2*numbers)
Inc r30
LPM r20, Z
rcall analysera
rjmp huvudsakliga

Så Z innehåller ZH:ZL som är samma som r31:r30 som är 0x0003 eftersom "siffror:" börjar vid 0x0001 och vi gånger med 2 för att initiera ZL och ZH vilket innebar att Z innehöll 0x0002, då vi ökas r30 (som är den nedre halvan av Z) så att nu Z = r31:r30 = 0x00:0x03 = 0x0003. När instruktionen LPM ombeds att ladda programminne från Z r20 tar det numret i Z, som är 0x0003 = 0b0000000000000011, och säger: "Okej, 0. lite är en 1, som innebär att jag vill ta den andra byten på adress 0b0000000000000001 vilket är den adress som jag får genom att flytta Z till höger en position (eller dividera med 2)"

Jag vill göra en sista sak här för att försöka göra den mindre förvirrande. Låt oss gå tillbaka till toppen av vårt program och sticka en .org uttalande där. Så har du

.org 0x0000
rjmp Init
.org 0x0008
nummer:
DB 0b01111111, 0b11011110, 0b01011110, 0b11010010
DB 0b01010010, 0b11000000

Kan du se vad jag har gjort? Jag har uttryckligen sagt PC att sticka mitt bord nummer på programminne adress 0x0008, som i binär 0b0000000000001000

(Minns att eftersom jag inte så att någon avbryter jag kan kan använda dessa minne utrymmen för vad jag vill.)

Sedan siffrorna: tabell startar på ovanstående adress, vad kommer att få laddas in r30 och r31 denna gång?

Multiplicera väl som tar itu med 2 och du får 0b0000000000010000 som avskiljer som 00000000:00010000 så som berättar att r31, ZH om du vill, är 0b00000000 och r30 eller ZL om du vill, är 0b00010000.

Övning 2: kontrollera detta med din analyzer genom mata r30.

Nu prova det här:

viktigaste:
LDI ZH, high(2*numbers)
LDI ZL, low(2*numbers)
adiw ZH:ZL, 3
LPM r20, Z
rcall analysera
rjmp huvudsakliga

Du bör peka på den 4: e nummer i vår lista sedan vi började på den första en och lagt 3 till adressen. Vad är den faktiska programminne adressen av detta nummer? Jo, programmet minnesadressen för den första i listan är 0x0008, som är 0b0000000000001000, och programmet minnet av den andra siffran i listan är också 0x0008. Fjärde numret program adress är också 0x0009 programminnet av det tredje numret i listan är 0x0009. Hur vi får det fjärde numret är börjar vi med sin adress 0b0000000000001001 och vi flytta vänster, 1 bit (dvs gånger med 2) för att få 0b0000000000010010 och detta ger ZH:ZL värdena för den första siffran på denna adress, dvs det tredje numret i vår lista, för att få den andra siffran lagras på samma adress (med andra ord den övre halvan av 16-bitars registret på adress 0x0009) vi bara lägga till en till den skiftade nummer. Vilket är 0b0000000000010011. Detta är antalet 0x13 i hex, eller 19 i decimal. Så vi vill ha ett tal som lagras på programminne adress nummer 9 och så vi ZH:ZL till 0:19 låt oss bevisa alla detta. Kan bara hålla detta nummer i r30 och r31 och se vad som kommer ur Z.

viktigaste:
LDI ZH, high(2*numbers)
LDI ZL, low(2*numbers)
LDI r31, 0
LDI r30, 19
LPM r20, Z
rcall analysera
rjmp huvudsakliga

Hör och häpna. Din LED visar 4. numret på vår lista.

Jag hoppas att detta har hjälpt människor att förstå vad händer med Z pekaren, hur programminne läggas ut, hur ADIW och LPM fungerar och varför de har att göra detta multipliceras med två grejer att få rätt byte data ur en viss minnesadress. Märka det finns två olika 16 bitars saker här. Själva programminne adressen är ett 16-bitars nummer, och registret på var och en av dessa adress är 16 bitar bred. Den första omständigheten därför Z har gjorts av 2 av våra 8-bitars arbetande register så att det kan hålla en komplett minnesadress, andra är därför måste vi multiplicera med 2 så vi kan få låga eller höga byte av data som lagras på varje adress.

Övning 3: lek med att placera data i olika minnesplatser, öka och minska r30 och r31 registren, vad händer när du startar på r31 = 0xFF och öka det? Också försöka använda X och Y pekare också.

Usch! Låt oss ta en paus och göra något roligt...

Se Steg
Relaterade Ämnen

AVR Assembler handledning 11

Välkommen till handledning 11!I den här korta guiden kommer vi slutligen att bygga den första delen av vårt sista projekt.Det första du bör göra är att gå till det allra sista steget i denna tutorial och titta på videon. Sedan komma tillbaka hit. [pa...

AVR Assembler handledning 6

Välkommen till Tutorial 6!Dagens handledning kommer att vara kort där vi kommer att utveckla en enkel metod att kommunicera data mellan en atmega328p och en med två portar ansluta dem. Vi kommer ta sedan tärningarna rullen från läraren 4 och registre...

AVR Assembler handledning 8

Välkommen till Tutorial 8!I denna kort tutorial ska vi ta lite av en skenmanöver från att införa nya aspekter av assembler programmering att visa hur man flytta våra prototyper komponenter till ett separat "tryckta" kretskort. Anledningen är att...

AVR Assembler handledning 10

Välkommen till handledning 10!Ledsen att det tog så lång tid för att få denna nästa avbetalning ut men detta är en ganska hektisk tid på året. I alla fall, är här det!Vi har kommit långt och du förmodligen redan är kompetenta nog att skriva många int...

AVR Assembler handledning 3

Välkommen till tutorial nummer 3!Innan vi börjar vill jag göra en filosofisk punkt. Inte vara rädd för att experimentera med kretsar och den kod som vi konstruerar i dessa tutorials. Ändra sladdar runt, lägga till nya komponenter, ta komponenter ut,...

AVR Assembler Tutorial 1

Jag har beslutat att skriva en serie tutorials om hur man skriver assembler program för den Atmega328p som är mikrokontroller används i Arduino. Om människor förblir intresserad fortsätter jag att lägga ut en en vecka eller så tills jag får slut på l...

AVR Assembler Övningsexempel 7

Välkommen till Övningsexempel 7!Idag vi första visar hur du rensar en knappsats och sedan visar hur du använder Analog ingång hamnarna för att kommunicera med knappsatsen.Vi kommer att göra med avbrott och en enda tråd som indata. Vi kommer tråd knap...

AVR Assembler Övningsexempel 9

Välkommen till Övningsexempel 9.Idag kommer vi att visa hur du kan styra både 7-segment display och en 4-siffrig display med våra ATmega328P och AVR assembler kod. I samband med detta får vi ta omvägar till hur du använder stacken för att minska anta...

AVR Assembler Tutorial 2

Denna handledning är en fortsättning på "AVR Assembler Tutorial 1"Om du inte har gått igenom Tutorial 1 bör du sluta nu och göra att man först.I den här guiden kommer vi fortsätta vår studie av assembler programmering av den atmega328p som använ...

AVR Assembler Övningsexempel 4

Välkommen till tutorial nummer 4!I den här guiden kommer vi att bygga en krets som kommer att simulera rullning av två tärningar. Sedan kommer vi först skriva en brute force-program som gör jobbet. Sedan kommer vi förenklar det programmet på olika sä...

En avancerad metod för Arduino & AVR programmering

Detta instructable är ett måste läsa för alla som är bekanta med core AVR chips och Arduino.Tja, mer konkret, när jag läste den instructable kommer du att kunna:1) vet väl skillnaden mellan AVR och Arduino.2) programmering Arduino med WinAVR & använd...

Utveckling styrelsen för Attiny84 mikrokontroller

Detta är en utveckling styrelse för Attiny84 mikrokontroller. Tha Attiny84 chip har 11 pins adresserbara med Arduino IDE, 8k flashminne för lagring av program och 512 byte ram tillgängligt för variablerna stack och program.En funktion av den Attiny84...

Hur man ladda program till en Arduino UNO från Atmel Studio 7

I denna korta Instructable kommer vi att lära sig att ladda ett program till en Arduino UNO ombord med Atmel Studio istället för Arduino IDE. Detta är användbart när du behöver utveckla ett program med fler advance funktioner eller på ett annat språk...

MRETV - Video, ljud och mycket mer från en standard Arduino!

MRETV - Video, ljud och mycket mer från en standard Arduino!Nu uppdaterad för Arduino 1.6.6 November 2015!Använd endast två resistorer och två dioder för att generera full skärm video. Text 47 x 29 8 x 8 tecken, dubbla vertikala upplösningen (47 x 57...

Älskling, jag krympte Arduino: flytta från Arduino till ATtiny och skriva din kod i ren AVR-C

Arduino är en stor hård- och mjukvaruplattform, men med alla dess funktioner är det också lite uppsvälld och ofta behöver du bara en liten del av alla funktioner. Projektet kräver ibland för att ha mindre och billigare enheter. Vad du behöver är ATti...

65xx teknik-församlingen språk programmering med W65C02SXB-handledning 1

Western Design Center (WDC) har beslutat att skriva en serie tutorials på hur du kommer igång med vår 65xx teknik och hur man skriver assembler program för 65xx familjen för ICs. Denna handledning kommer att baseras på använda det Standard W65C02 chi...

AVR fuse grunderna: kör en avr med en extern klocka

säkringar är bland de svåraste ämnen som jag stött på samtidigt lära sig om programmering microcontrollers. Även efter att söka och läsa flitigt, kunde jag fortfarande inte lyckas rensa mitt begrepp om dem. Men sedan jag började lära dem ta en i tage...

AVR programmering med Arduino, AVRdude och AVR-gcc

AVR är en gemensam, billig typ av mikro-controller som kan verka skrämmande att arbeta med, men oroa dig inte! När du har Ställ in grundläggande kunskap och kan de bli inte bara nyttigt, men viktigt att nya projektidéer som du drömmer upp!Denna handl...

Idiot's Guide till programmering AVR: s på de billiga (med Arduino IDE!)

Mikrokontroller är, utan tvekan, fantastiska små saker. De är mångsidiga, kraftfull och mycket små. Tyvärr, den sistnämnda drag också delas av både min plånbok och mina kunskaper i programmering. Min förståelse av C är dålig, och jag har knappt råd a...