Taula de continguts:

Tutorial AVR Assembler 1: 5 passos
Tutorial AVR Assembler 1: 5 passos

Vídeo: Tutorial AVR Assembler 1: 5 passos

Vídeo: Tutorial AVR Assembler 1: 5 passos
Vídeo: AVR Ассемблер. Урок 1. Вводный. AVR Assembler. Lesson 1. Promo. 2024, De novembre
Anonim
Tutorial AVR Assembler 1
Tutorial AVR Assembler 1

He decidit escriure una sèrie de tutorials sobre com escriure programes de llenguatge ensamblador per a l'Atmega328p, que és el microcontrolador utilitzat a l'Arduino. Si la gent continua interessada, continuaré posant-ne una a la setmana aproximadament fins que se m'acabi el temps lliure o la gent deixi de llegir-los.

Estic executant Arch Linux i estic treballant en un atmega328p-pu configurat en una taula de treball. Podeu fer-ho de la mateixa manera que jo o simplement connectar un arduino a l’ordinador i treballar al microcontrolador d’aquesta manera.

Escriurem programes per al 328p com el que hi ha a la majoria d’arduino, però heu de tenir en compte que aquests mateixos programes i tècniques també funcionaran per a qualsevol dels microcontroladors Atmel i més endavant (si hi ha interès) treballarem amb alguns els altres també. Els detalls del microcontrolador es poden trobar als fulls de dades d’Atmel i al Manual d’instruccions. Els adjunto a aquest instructiu.

Això és el que necessiteu:

1. Una pissarra

2. Un Arduino, o simplement el microcontrolador

3. Un ordinador amb Linux

4. L'assemblador d'avra que utilitza git: git clone https://github.com/Ro5bert/avra.git o si utilitzeu ubuntu o un sistema basat en debian, només heu d'escriure "sudo apt install avra" i obtindreu tant l'assemblador avr i avrdude. Tanmateix, si obteniu l'última versió amb github, també obtindreu tots els fitxers d'inclusió necessaris, és a dir, que ja tenen els fitxers m328Pdef.inc i tn85def.inc.

5. avrdude

El conjunt complet dels meus tutorials del muntador AVR es pot trobar aquí:

Pas 1: construïu una junta de proves

Construeix una placa de proves
Construeix una placa de proves

Simplement podeu utilitzar el vostre arduino i fer-ho tot en aquests tutorials, si voleu. Tanmateix, com que parlem de codificació en llenguatge assemblador, la nostra filosofia és intrínsecament eliminar tots els periferals i interactuar directament amb el propi microcontrolador. Llavors, no creieu que seria més divertit fer-ho d’aquesta manera?

Per a aquells que hi estiguin d'acord, podeu extreure el microcontrolador del vostre arduino i començar per construir un "Breadboard Arduino" seguint les instruccions aquí:

A la imatge mostro la configuració que consisteix en dos Atmega328p independents en una gran placa de taula (vull poder mantenir el tutorial anterior connectat i carregat en un microcontrolador mentre treballava al següent). Tinc la font d'alimentació configurada perquè el carril superior sigui de 9V i tots els altres estiguin a 5V del regulador de voltatge. També faig servir un tauler FT232R per programar els xips. Els vaig comprar i els vaig posar carregadors d’arrencada jo mateix, però si només n’heu tret un d’Arduino, ja està bé.

Tingueu en compte que, si ho proveu amb un ATtiny85, podeu obtenir el programador Sparkfun Tiny aquí: https://www.sparkfun.com/products/11801# i simplement connectar-lo al port USB de l'ordinador. Primer haureu d’instal·lar un carregador d’arrencada a l’Attiny85 i la manera més senzilla és només utilitzar l’IDE Arduino. Tanmateix, haureu de fer clic al fitxer i a les preferències i, a continuació, afegir aquest URL de taulers nous: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json que us permetrà instal·lar el carregador d'arrencada (si el vostre ATtiny85 encara no el venia).

Pas 2: instal·leu l'Assembler i Avrdude

Ara podeu descarregar i instal·lar l'assemblador i avrdude des dels enllaços que apareixen al primer pas d'aquest tutorial. És probable que si ja heu estat treballant amb Arduino's, ja tingueu avrdude instal·lat.

Després d'haver instal·lat avra, notareu que hi ha un subdirectori que s'inclou amb el nom de "fonts" i, dins d'aquest directori, hi ha un munt de fitxers d'inclusió. Aquests són tots els microcontroladors que podeu programar amb avra. Notareu de seguida que no hi ha cap fitxer per al 328p que estem utilitzant aquí. N’he adjuntat un. El fitxer s’hauria de dir m328Pdef.inc i hauríeu de posar-lo dins del directori inclou o qualsevol altre lloc que vulgueu. L’inclourem als nostres programes de llenguatge assemblador. Tot el que fa és donar a cadascun dels registres dels noms del microcontrolador del full de dades de manera que no haguem d’utilitzar els seus noms hexidecimals. El fitxer d'inclusió anterior conté "directives pragma", ja que va ser dissenyat per a la programació C i C ++. Si us canseu de veure que l'assemblador escolta les queixes "ignorant la directiva pragma", només cal que aneu al fitxer i suprimiu o comenteu totes les línies que comencen per #pragma

D’acord, ara que teniu el microcontrolador a punt, el muntador i el programador a punt, podem escriure el nostre primer programa.

Nota: Si utilitzeu ATtiny85 en lloc de l'ATmega328P, necessiteu un fitxer d'inclusió diferent anomenat tn85def.inc. Jo també l’adjuntaré (tingueu en compte que l’havia de dir tn85def.inc.txt perquè Instructables em permetés carregar-lo.) Tanmateix, si teniu l’assemblador d’avra de github, ja teniu aquests dos fitxers. Per tant, recomano obtenir-lo i compilar-lo vosaltres mateixos: git clone

Pas 3: Hello World

L’objectiu d’aquest primer tutorial és construir el primer programa estàndard que s’escriu quan s’aprèn qualsevol idioma nou o s’explora qualsevol nova plataforma electrònica. "Hola món!." En el nostre cas, simplement volem escriure un programa de llenguatge ensamblador, muntar-lo i penjar-lo al nostre microcontrolador. El programa farà que s’encengui un LED. Fer que un LED parpellegi com fan el programa hola world normal d’Arduino és en realitat un programa molt més complicat en llenguatge ensamblador i, per tant, encara no ho farem. Escriureem el codi més senzill dels "ossos nus" amb una pelussa mínima innecessària.

Primer, connecteu un LED de PB5 (vegeu el diagrama pinout), que també s’anomena sortida digital 13 en un arduino, a una resistència de 220 ohm, i després a GND. És a dir, PB5 - LED - R (220 ohm) - GND

Ara per escriure el programa. Obriu el vostre editor de text preferit i creeu un fitxer anomenat "hello.asm"

; hola.asm

; encén un LED connectat a PB5 (sortida digital 13).include "./m328Pdef.inc" ldi r16, 0b00100000 out DDRB, r16 out PortB, r16 Start: rjmp Start

L’anterior és el codi. El revisarem línia per línia en un minut, però primer ens assegurem que puguem que funcioni al vostre dispositiu.

Després de crear el fitxer, en un terminal el muntareu de la manera següent:

avra hola.asm

això reunirà el vostre codi i crearà un fitxer anomenat hello.hex que el podem carregar de la següent manera:

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

si utilitzeu un arduino de taulers de suport, haureu de prémer el botó de restabliment de l'arduino de taulers de suport just abans d'executar l'ordre anterior. Tingueu en compte que també pot ser que hàgiu d'afegir un sudo al davant o executar-lo com a root. Tingueu en compte també que en alguns arduino (com l’Arduino UNO) probablement haureu de canviar la taxa de bits a -b 115200 i el port -P / dev / ttyACM0 (si obteniu un error d’avrdude sobre una signatura de dispositiu no vàlida, només cal afegir un - F a l'ordre)

Si tot ha funcionat com hauria de tenir, ara tindreu un LED encès ….. "Hola món!"

Si utilitzeu ATtiny85, l'ordre avrdude serà:

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

Pas 4: Hello.asm, línia per línia

Per acabar aquest tutorial introductori, passarem el programa hello.asm línia per línia per veure com funciona.

; hola.asm

; encén un LED connectat a PB5 (sortida digital 13)

Tot el que passa després d'un punt i coma és ignorat per l'assemblador i, per tant, aquestes dues primeres línies són simplement "comentaris" que expliquen el que fa el programa.

.inclou "./m328Pdef.inc"

Aquesta línia indica al muntador que inclogui el fitxer m328Pdef.inc que heu descarregat. És possible que vulgueu posar-ho en un directori de fitxers d’inclusió similars i, a continuació, canviar la línia anterior per apuntar-s’hi.

ldi r16, 0b00100000

ldi significa "càrrega immediata" i diu a l'assemblador que agafi un registre de treball, r16 en aquest cas, i que carregui un número binari, 0b00100000 en aquest cas. El 0b de davant diu que el nostre número és en binari. Si volguéssim, podríem haver triat una altra base, com ara l’hexidecimal. En aquest cas, el nostre nombre hauria estat 0x20, que és hexidecimal per a 0b00100000. O podríem haver utilitzat 32, que és la base 10 decimal per al mateix nombre.

Exercici 1: proveu de canviar el número de la línia superior a hexidecimal i després a decimal al codi i verifiqueu que encara funcioni en cada cas.

Utilitzar binari és el més senzill, però, per la manera com funcionen els ports i els registres. Discutirem els ports i els registres de l'atmega328p amb més detall en futurs tutorials, però de moment només diré que estem utilitzant r16 com a "registre de treball", és a dir, que només ho farem servir com a variable que emmagatzemem. Un "registre" és un conjunt de 8 bits. És a dir, 8 punts que poden ser 0 o 1 ("desactivat" o "activat"). Quan carreguem el número binari 0b00100000 al registre mitjançant la línia anterior, simplement hem emmagatzemat aquest número al registre r16.

fora de DDRB, r16

Aquesta línia indica al compilador que copiï el contingut del registre r16 al registre DDRB. DDRB significa "Data Direction Register B" i estableix els "pins" a PortB. Al mapa de fixació del 328p podeu veure que hi ha 8 pins identificats amb PB0, PB1, …, PB7. Aquests pins representen els "bits" de "PortB" i quan carreguem el número binari 00100000 al registre DDRB diem que volem que PB0, PB1, PB2, PB3, PB4, PB6 i PB7 es configurin com a pins INPUT ja que tenen Hi ha 0, i PB5 es defineix com a pin OUTPUT ja que posem un 1 en aquest lloc.

fora de PortB, r16

Ara que hem fixat les direccions dels pins, ara podem fixar-los els voltatges. La línia anterior copia el mateix número binari del nostre registre d’emmagatzematge r16 a PortB. Això estableix tots els pins a 0 volts, excepte el pin PB5 a HIGH, que és de 5 volts.

Exercici 2: Agafeu un multímetre digital, connecteu el cable negre a terra (GND) i, a continuació, proveu cadascun dels pins PB0 a PB7 amb el cable vermell. Les tensions de cadascun dels pins són exactament les corresponents a posar 0b00100000 al PortB? Si n’hi ha que no ho són, per què creieu que és així? (veure el mapa de pins)

Començar:

rjmp Inici

Finalment, la primera línia anterior és una "etiqueta" que etiqueta un punt del codi. En aquest cas, etiqueteu aquest punt com a "Inici". La segona línia diu "salt relatiu a l'etiqueta Inici". El resultat net és que l’ordinador es col·loca en un bucle infinit que continua mantenint la bicicleta cap a l’inici. Ho necessitem perquè no podem acabar el programa ni caure d’un penya-segat; el programa només ha de continuar funcionant perquè la llum es mantingui encesa.

Exercici 3: traieu les dues línies anteriors del vostre codi perquè el programa caigui d'un penya-segat. Què passa? Hauríeu de veure alguna cosa que s’assembla al programa tradicional "parpellejar" que utilitza Arduino com a "hola món!". Per què creieu que actua així? (Penseu en què ha de passar quan el programa cau d'un penya-segat …)

Pas 5: Conclusió

Si heu arribat fins aquí, enhorabona! Ara podeu escriure codi de muntatge, muntar-lo i carregar-lo al microcontrolador.

En aquest tutorial heu après a utilitzar les ordres següents:

ldi hregister, el número carrega un número (0-255) en un registre de la meitat superior (16-31)

ioregister, registre copia un número d'un registre de treball a un registre d'E / S

rjmp label salta a la línia del programa etiquetada per "label" (que no pot estar a més de 204 instruccions de distància, és a dir, salt relatiu)

Ara que aquests conceptes bàsics estan fora del camí, podem continuar escrivint codi més interessant i circuits i dispositius més interessants sense haver de discutir la mecànica de compilació i càrrega.

Espero que us hagi agradat aquest tutorial introductori. Al següent tutorial afegirem un altre component del circuit (un botó) i ampliarem el nostre codi per incloure ports d'entrada i decisions.

Recomanat: