- Stahuj zápisky z přednášek a ostatní studijní materiály
- Zapisuj si jen kvalitní vyučující (obsáhlá databáze referencí)
- Nastav si své předměty a buď stále v obraze
- Zapoj se svojí aktivitou do soutěže o ceny
- Založ si svůj profil, aby tě tví spolužáci mohli najít
- Najdi své přátele podle místa kde bydlíš nebo školy kterou studuješ
- Diskutuj ve skupinách o tématech, které tě zajímají
Studijní materiály
Hromadně přidat materiály
AWR - úvod
Y36SAP - Struktura a architektura počítačů
Hodnocení materiálu:
Popisek: úvod do AWR
Zjednodušená ukázka:
Stáhnout celý tento materiálUčební materiál ASM AVR
1
Úvod do programování v AVR asembleru.
Výběr kapitol z již vyprodané knihy vydané v BEN Praha 2003
1.1 Úvod
Vladimír Váňa
Učební materiál poskytuje základní informace důležité pro aplikaci jednočipových mikrořadičů AVR firmy
ATMEL. Navazuje na učební materiál „Mikrořadiče Atmel AVR“, který seznamuje žáky především s
RISCovou architekturou mikrokontrolerů ATMEL a se souborem instrukcí a dále obsahuje praktický návod na
ISP programátor s ATTINY2313 a jednoduchý vývojový kit s ATmega8515 - popisuje tedy především
hardware a instrukční soubor. Jeho znalost se nám bude hodit v tomto dalším učebním materiálu, který si klade
za cíl seznámit především začátečníky s tvorbou programového vybavení pro mikrokontroléry AVR. K tvorbě
programového vybavení je potřeba mít vhodné nástroje a znalosti, jak tyto nástroje používat. Mají vývojáři co
nejvíce usnadnit práci a zlevnit a zrychlit vývoj konkrétních aplikací. Těmito nástroji jsou překladače z kódu
nějakého programovacího jazyka do strojového kódu MCU AVR, simulátory, emulátory a vlastní vývojové
prostředí. Pokud jde o programovací jazyky pro AVR mikrořadiče, máme k dispozici jednak různé jazyky
symbolických adres, jednak vyšší programovací jazyky C/C++, Pascal a Basic. U „velkých“ počítačů (mezi ně
můžeme počítat i počítače PC, pokud je budeme srovnávat s „jednočipáky“) byl dlouhou dobu nejrozšířenějším a
nejžádanějším programovacím jazykem C++ a C. Podle některých studií byl v poslední době předstižen
jazykem Java. Jde o objektový jazyk odvozený od C a C++ , původně vyvíjený pro „vestavěné (Embedded)
systémy“, což je odborný termín pro běžná elektronická zařízení ( typu pračky, mikrovlnné trouby atd.)
ovládaná zabudovaným mikroprocesorem. Firma SUN, která tento jazyk vyvíjela, si brzy uvědomila vzrůstající
důležitost WWW a možnosti využít Javu pro programování aplikací pro WWW. Proto si většinou spojujeme
Javu právě s internetem. Rozšířenost Javy a její výhody vedly v poslední době k tomu, že si ji všimli ti, kterým
byla původně určena – vývojáři embedded zařízení. Jako příklad si můžeme uvést programování mobilních
telefonů v Javě. Ze vzrůstající oblíbenosti Javy i při vývoji programového vybavení pro embedded zařízení lze
usuzovat, že může zasáhnout i vývoj pro MCU AVR (viz např. projekt / knihovna Javy JEPES dánské firmy
Mjolner Informatics z jejichž www stránek si lze zdarma stáhnout funkční demo verzi umožňující programovat
AT90S8515 v Javě).
Kromě ulehčení práce vývojáře je další výhodou použití vyšších programovacích jazyků při tvorbě
programového vybavení pro MCU, či jednočipové mikropočítače i to, že zdrojový kód programu určeného
původně pro určitý typ MCU se dá snadněji přepsat na zdrojový kód jiného typu MCU, jiného výrobce než
přepisovat kód, který je více závislý na hardware (asembler). Jako příklad mohu uvést např. IAR Embedded
Workbench, což je jednotné vývojové prostředí s velkým počtem překladačů z jazyka C++ do strojových kódů
různých jednočipových mikropočítačů a mikrořadičů, samozřejmě včetně ATMEL AVR, x51, PIC atd. Stále
však existuje jistá třída úloh, kterou ve vyšších programovacích jazycích nelze realizovat, nebo k nimž nemáme
v příslušném vyšším jazyce zabudovanou podporu. V tom případě musíme použít jazyk symbolických adres –
asembler. Nejefektnější v takovém případě je napsat aplikaci v vyšším programovacím jazyce a jen její část
v asembleru. Proto i v případě, že používáme vyšší programovací jazyky, je dobré mít alespoň základní znalosti
programování v asembleru. K jejich získání má posloužit tento výukový materiál. Programování AVR aplikací
ve vyšších programovacích jazycích je předmětem dalších výukových materiálů.
Asemblery
Jazyky symbolických adres patří mezi nejstarší programovací jazyky, se kterými se setkáváme již u počítačů
první generace, tedy již před několika desítkami let. Dříve, než se u počítačů objevily, programovalo se přímo ve
strojovém kódu, tj. většinou v binární, oktalové nebo hexadecimální reprezentaci instrukcí počítače. Všechny
objekty, s nimiž počítač pracoval, byly pochopitelně označovány pouze číselně. Např. naplnění registru 16
konstantou má ve strojovém jazyce mikrořadiče ATMEL AVR tvar:
Učební materiál ASM AVR
2
1100 1111 0000 0110
Je zřejmé, že programování ve strojovém jazyce je obtížné a nepřehledné a mohlo vyhovovat jen v úplných
začátcích, kdy programy byly krátké a jednoduché.
Se zdokonalováním technického vybavení rostly nároky na programy a programování ve strojovém jazyce
začalo být neúnosné. Brzo se však zjistilo, že pracnost programování lze značně snížit, zrušíme-li nutnost
označovat objekty v instrukcích číselně (vyhovuje stroji) a zavedeme-li symbolické označování objektů
(vyhovuje člověku) s tím, že vazbu symbolů na jejich číselné vyjádření nebude provádět programátor, ale zajistí
ji specializovaný program – překladač. Tak vznikly jazyky symbolických adres, v nichž se mohly operační znaky
instrukcí a jejich operandy označovat symboly, a překladače jazyků symbolických adres (asemblery), které
překládaly symbolický jazyk do strojového jazyka.
V dalším vývoji byly do jazyků symbolických adres doplňovány nové prostředky (např.makrojazyk, makra) ,
přičemž vývoj byl obvykle spjat s rozšířením symbolických objektů. Makrojazyk je např. založen na možnosti
pojmenovat posloupnost instrukcí, bez makrojazyka bylo možné pojmenovávat pouze objekty v instrukcích.
Brzy se ukázalo, že programátorovi lze práci ještě více usnadnit, zbavíme-li závislosti na instrukční síti počítače,
se kterou byl spjat i při programování v jazyce symbolických adres. Objevily se proto jazyky nezávislé na
počítači, které jsou navrženy tak, aby programátor instrukční část počítače vůbec nemusel znát. Jazyky
symbolických adres však nebyly zcela nahraženy, neboť stále existují úlohy, které ve vyšších programovacích
jazycích nelze vyřešit. Při programování v jazyce symbolických adres se totiž dostáváme do nejužšího styku se
systémem, s hardware.
Velké počítače obvykle řeší úlohy, snadno řešitelné pomocí vyšších programovacích jazyků, jednočipové
mikropočítače a mikrořadiče naopak úlohy, řešitelné asemblery. Vyšší programovací jazyky jsou
implementovány řadou výrobců a pro mnoho různých procesorů pracujících pod různými operačními systémy,
často pro určitý operační systém a procesor existuje i dosti velký počet různých překladačů z téhož jazyka.
Různé verze překladačů téhož jazyka se liší rychlostí překladu, velikostí a rychlostí výsledného kódu, komfortem
vývojového prostředí, knihovnami atd. Definice vlastního vyššího programovacího jazyka , jeho lexikální
symboly, syntaxe, sémantika, je však často dána nějakou normou, ať mezinárodní (např. ANSI C, ANSI C++)
nebo podnikovou (Java u SUNu). Proto různé příručky či učebnice např. jazyka C,C++, Javy jsou použitelné při
práci s různými překladači. Můžeme říci: programuji v C++, Javě, Pascalu, SQL, C# . Prohlásit „programuji
v asembleru“ již není tak jednoznačné. Z toho, co jsme o asemblerech zatím uvedli je zřejmé, že máme mnoho
různých asemblerů. Jednak různé procesory mají různé instrukční soubory, jednak jsou rozdíly i mezi asemblery
pro určitý konkrétní typ procesoru. Vždy je nutné prostudovat dokumentaci k příslušnému asembleru. My se
v tomto výukovém materiálu budeme věnovat pouze jednomu asembleru a to ATMEL AVR asembleru pro
mikrořadiče řady ATmega či ATTINY. Tento asembler poskytuje zdarma firma ATMEL. Je naprosto odlišný .
od asemblerů např. pro 8086 či x51 nebo PIC. Na druhé straně bude mít hodně společného s jinými asemblery
pro MCU řady ATmega, např. s IAR AVR asemblerem, takže informace z tohoto výumového materiálu
můžeme s určitou dávkou opatrnosti použít i při práci s jinými asemblery pro AVR.
V následujících kapitolách se nejprve seznámíme se strukturou AVR programů v asembleru, práci s registry,
porty, použitím SRAM, řízením chodu programů a prováděním výpočtů v AVR asemblerů. Rovněž je uveden
popis ATMEL AVR asembleru, tak, jak ho uveřejnil výrobce v helpu k tomuto asembleru. Tyto kapitoly
obsahují jen fragmenty kódů. Proto na konci knihy je pro začátečníky uvedeno několik jednoduchých, ale
úplných programů, odzkoušených s ATmega8515 v startkitu uvedeném v příloze k tomuto výukovému
materiálu.
Struktura AVR programů v assembleru
Tato kapitola pojednává o základní struktuře programu v assembleru, typické pro ATmega
assembler. Popisuje komentáře, hlavičkové informace, kód při startu programu a obecnou
strukturu programu.
Komentáře
Stejně jako u jiných programovacích jazyků je i u AVR assembleru dobré doplňovat zdrojový
kód poznámkami – komentáři. Slouží k porozumění napsaného kódu, který po nás bude někdo
Učební materiál ASM AVR
3
i číst, ale dobrý komentář dobře poslouží i autorovi programu. Po několika měsících si již
těžko budeme pamatovat, co jsme zamýšleli při použití nějaké instrukce, různé finty, význam
registrů atd. Je dobré okomentovat každou část programu, podprogramu, tabulek.
Komentář začíná středníkem. Vše, co je za ním na stejné řádce bude překladač ignorovat.
V případě potřeby napsat komentář na několik řádek je třeba začít každou řádku středníkem.
Např. každý program v assembleru by měl začínat nějak takto:
;
; test1.asm, Program na testováni pokusné desky s ATmega8515
; napsal X.Y., poslední verze: 10.5.2007
;
Jednořádkový komentář je definován přidáním středníku za příkaz na této řádce. Např.:
LDI R16,0x0B ; konstanta je uložena do registru
MOV R17,R16 ; a dále kopírována do dalšího registru
Začátek programu
Je dobré, uvést na začátku v komentářích název a funkci programu, autora, verzi a další
komentáře. Dále by mělo být uvedeno, pro jaký typ procesoru je program napsán, důležité
konstanty a seznam jmen registrů.
Uvedení typu procesoru, resp. MCU je důležité, protože program nemusí být funkční na
jiných MCU bez provedení odpovídajících změn. Některým typům MCU mohou scházet
některé instrukce , neboť kompletní instrukční soubor není implementován u všech typů. Dále
každý typ má své typické množství paměti EEPROM i interní SRAM. Všechny tyto
specifické vlastnosti jsou obsažené v hlavičkových souborech, které jsou pojmenované
mxxxxdef.inc, kde xxxx označuje typ MCU tj. např. 8515 atd. pro MCU z řady ATmega,
popř. tnxxxxdef.inc, např. 2313 pro MCU z řady ATTINY. Tyto soubory jsou k dispozici na
CD a webu firmy ATMEL, či ve složce appnotes v nainstalovaném AVR Studiu. K dobrému
programátorskému stylu patří uvádět tyto soubory na začátku programu jako parametr
direktivy assembleru INCLUDE. Mělo by to vypadat nějak takto:
.NOLIST ; vypíná se generování listingu
.INCLUDE "C:\avrtools\appnotes\m8515def.inc" ; import souboru
.LIST ; opětovně se zapíná generování listingu
Cestu, kde lze nalézt soubor, je nutné uvádět pouze v případě, kdy se nachází v jiném
adresáři, než je umístěn náš assemblerovský program.
Při překladu je defaultně zapnuto generování listingu, což může znamenat vygenerování
Učební materiál ASM AVR
4
velmi dlouhého listingu (*.lst) v případě, že obsahuje i hlavičkový soubor. Direktiva
NOLIST vypne generování listingu do té doby, než je direktivou LIST znovu zapnut.
Krátce se podíváme, jak vypadá hlavičkový soubor. Nejdříve je definován typ procesoru :
.DEVICE ATmega8515 ; použitý typ MCU
Tato direktiva vyvolá ve výsledku chybovou hlášku, jsou –li v programu použity instrukce,
které nejsou definovány pro příslušný typ MCU. Nemusíte tuto direktivu používat v svém
uživatelském programu, protože je již obsažena v hlavičkovém souboru.
Hlavičkový soubor definuje registry XH, XL, YH, YL, ZH a ZL. Jsou potřebné v případě
používání 16-bitových ukazatelů X, Y nebo Z k oddělenému přístupu k hornímu nebo
dolnímu bytu ukazatele. V hlavičkovém souboru jsou také definovány I/O brány, takže např.
PORTB se převádí na hex 18. Jména portů jsou definována stejně, jako jsou definována
v katalogových listech pro příslušný typ MCU. Totéž se to aplikuje na samostatné bity v
portech. Např. při čtení bitu 3 z portu B, můžeme použít jméno PINB3, stejně jako v
katalogu.
Praktická poznámka: pokud zapomeneme uvést hlavičkový soubor do kódu programu, projeví
se to při překladu jako velký počet chyb. Na druhé straně, některé chyby se při překladu
nezobrazí, vlivem chyby vlastního překladače. V Atmelovském assembleru se scházející
návěští nebo konstanta neprojeví jako chyba, ale překladač předpokládá, že je to nula.
Dále na začátku programu obvykle uvádíme definice registrů tj..:
.DEF mpr = R16 ; definuje nové jméno pro registr R16
Výhodou je mj. i to, že zde máme kompletní seznam již použitých registrů a vidíme, které
registry se nepoužívají. Pojmenování registrů snižuje možnost konfliktů při jejich používání a
jména se snadněji pamatují.
Na začátku zdrojového souboru se také definují konstanty, zvláště ty, které se používají
v různých částech programu. Takovou konstantou je například kmitočet krystalu s kterým
program počítá při sériové komunikaci, např.
.EQU fq = 4000000 ; definice frekvenci XTalu
Po uvedení hlavičky programu , musí být uveden začátek (start) kódu programu. Na začátku
kódu jsou umístěny reset a vektory přerušení. Protože vyžadují relativní skoky, musíme
umístit odpovídající obsluhy přerušení za sebou. Je zde ponechán prostor i pro ostatní
podprogramy , před umístěním vlastního, hlavního programu.
Hlavní program vždy začíná nastavením registrů na default hodnoty, inicializací ukazatele
zásobníku a použitých hardwarových prvků. Následující kód je typický pro program.
Učební materiál ASM AVR
5
Struktura programového kódu
Ukážeme si standartní tvar programu pro ATmega , který můžete používat , po úpravách, pro
vytváření vlastních programů s 8515 či jinými typy.
; ***************************************************************
; * *
; * *
; * *
; * *
; * *
; * (C)2007 by poslední zmena: *
; ***************************************************************
;
; pozadavky na hardware:
;
; vlastnosti software:
;
.NOLIST
.INCLUDE "C:\Program Files\Atmel\avr tools\AVR assembler2\appnotes\m8515def.inc"
.LIST
;
; konstanty
;
.EQU xyz = 12345
;
; pouzite registry
;
.DEF mpr = R16
;
; začátek kodu
;
.CSEG
.ORG $0000
;
; Reset- a vektory preruseni
;
rjmp Start ; Reset-vector
rjmp IInt0 ; External Interrupt Request 0
rjmp IInt1 ; External Interrupt Request 1
rjmp TCpt1 ; Timer/Counter1 Capture event
rjmp TCmpA ; Timer/Counter1 Compare match A
rjmp TCmpB ; Timer/Counter1 Compare match B
rjmp TOvf1 ; Timer/Counter1 Overflow
rjmp TOvf0 ; Timer/Counter0 Overflow
rjmp URxAv ; Uart Rx char available
rjmp UTxDe ; Uart Tx data register empty
rjmp UTxCp ; Uart Tx complete
rjmp AnaCp ; Analog comparator
;
; ************** obsluhy preruseni ********
;
; External Interrupt 0
;
IInt0:
reti
;
; External Interrupt 1
;
Učební materiál ASM AVR
6
IInt1:
reti
;
; Timer/Counter 1, Capture event
;
TCpt1:
reti
;
; Timer/Counter 1, Compare match interrupt A
;
TCmpA:
reti
;
; Timer/Counter 1, Compare match interrupt B
;
TCmpB:
reti
;
; Timer/Counter 1, Overflow interrupt
;
TOvf1:
reti
;
; Timer/Counter 0, Overflow interrupt
;
TOvf0:
reti
;
; SPI Serial Transfer Complete interrupt
;
SIStc:
reti
;
; Uart Rx Complete Interrupt
;
URxAv:
reti
;
; Uart Data register empty interrupt
;
UTxDe:
reti
;
; Uart Tx complete interrupt
;
UTxCp:
reti
;
; Analog comparator interrupt
;
AnaCp:
reti
;
; **************** konec podprogramu obsluh preruseni ***********
;
; ruzne podprogramy
;
; **************** konec casti podprogramu ***************
;
; ******************** hlavni program ****************************
;
Učební materiál ASM AVR
7
; zde zacina hlavni program
;
Start:
rjmp start
Registry
Registr je specielní paměť s kapacitou 8 bitů, kterou si můžeme představit takto:
7 6 5 4 3 2 1 0
Vidíme, že očíslování těchto bitů je takové, že nejméně významný bit začíná nulou (20 = 1).
Registr může obsahovat čísla od 0 do 255 (kladná čísla, neobsahující záporné hodnoty), nebo
od -128 do +127 (celá čísla s znaménkovým bitem v bitu 7), nebo hodnoty representované
znaky v ASCII kódu (např. 'A'), nebo jen osm osamocených bitů nemajících dohromady
nějaký význam (např. pro osm signálů sloužících k zapínání/vypínání nějakých vnějších
zařízení jako např. signalizačních LED, spínání pomocných relé, nebo naopak ke snímání
stavu vnějších kontaktů apod.).
Specielní charakter registrů při srovnání s jinou pamětí se projeví tím, že
Mohou být použity přímo registrovými instrukcemi,
Operace s jejich obsahem potřebují instrukce s pouze jedním slovem,
Jsou spojeny přímo s centrální procesorovou jednotkou, s akumulátorem,
jsou zdrojem i cílem při výpočtech, provádění instrukcí.
AVR MCU mají 32 registrů, označené R0 až R31. Můžeme jim však přiřadit další jména
pomocí assemblerovské direktivy. Například:
.DEF MujRegistr = R16
Přitom direktiva assembleru, jako je tato není assemblerem přeložena do nějakého kódu
spustitelném na AVR cílovém čipu. Místo používání jména registru R16 můžeme nyní
používat vlastní, námi definované, jméno MujRegistr, které můžeme použít místo R16 v
příkazech. Takto napíšeme v zdrojovém textu o něco více znaků při používání tohoto registru,
ale máme možnost mít název registru spojen s významem jeho obsahu.
Použití příkazové řádky
LDI MujRegistr, 150
znamená: load the number 150 immediately to the register R16, LoaD Immediate (ulož číslo
150 přímo do registru R16). Tato instrukce uloží pevnou hodnotu nebo konstantu do tohoto
registru. Následné přeložení tohoto kódu do programové paměti AVR čipu vypadá nějak
takto:
000000 E906
Učební materiál ASM AVR
8
Kód instrukce LDI, stejně jako cílový registr (R16) i hodnota konstanty (150) jsou částí
hodnoty E906, i když to není snadno vidět. Není nutné však abychom (ručně) vytvářeli sami
tento strojový kód, protože to je úkolem překladače – assembleru, který sám vygeneruje
E906.
V instrukci mohou být použity dva různé registry. Nejjednodušší instrukcí tohoto typu je
instrukce MOV. Ta kopíruje obsah jednoho registru do druhého registru, jako toto:
.DEF MujRegistr = R16
.DEF DalsiRegistr = R15
LDI MujRegistr, 150
MOV DalsiRegistr, MujRegistr
První dva řádky tohoto programu jsou direktivy které definují nová jména registrů R16 a R15
pro assembler. Tyto řádky nevytvářejí žádný kód pro AVR. Řádky zdrojového kódu s LDI a
MOV vytvářejí kód:
000000 E906
000001 2F01
Tyto příkazy zapisují 150 do registru R16 a kopírují jeho obsah do cílového registru R15.
Důležitá poznámka:
První registr je vždy cílový, zapisuje se do něho výsledek!
(Pro začátečníka je to trochu nezvyklé, protože jsme, např. při psaní, zvyklí spíše na pohyb
zleva doprava. Je to však obvyklá konvence, nicméně je to jeden
Vloženo: 17.05.2009
Velikost: 1,19 MB
Komentáře
Tento materiál neobsahuje žádné komentáře.
Copyright 2024 unium.cz