- 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álz důvodů, proč se
začátečníkům zdá assembler být složitý.)
Rozdílné registry
Když začínáme programovat v AVR assembleru, můžeme zkusit napsat místo výše
uvedených řádků programu kód, který vypadá např. takto :
.DEF DalsiRegistr = R15
LDI DalsiRegistr, 150
To je ale špatně! Protože: pouze registry od R16 do R31 se smějí používat v instrukci LDI
- uložení konstanty přímo do registru, R0 až R15 přitom nelze použít k tomuto účelu.
Toto omezení není příliš pěkné, ale musíme na něj pamatovat při programování pro AVR.
Existuje jedna výjimka z tohoto pravidla: nastavení registru na nulu. Příkaz
CLR MujRegistr
Učební materiál ASM AVR
9
je platný pro všechny registry.
Kromě omezení u instrukce LDI je stejné omezení na používání stejné třídy registrů i u
následujících dalších instrukcí:
ANDI Rx,K ; bitové And registru Rx s konstantní hodnotou K,
CBR Rx,M ; vymazání všech bitů v registru Rx, které jsou nastaveny na jedničku
v konstantní masce hodnoty M,
CPI Rx,K ; srovnání obsahu registru Rx s konstantní hodnotou K,
SBCI Rx,K ; odečtění konstanty K a aktuální hodnoty příznaku přenosu od aktuální
hodnoty registru Rx a uložení výsledku do registru Rx,
SBR Rx,M ; nastavení všech bitů v registru Rx na jedničku, které jsou jedničkové
k konstantní masce M,
SER Rx ; nastavení všech bitů v registru Rx na jedničku (rovná se LDI Rx,255),
SUBI Rx,K ; odečtění konstanty K od obsahu registru Rx a uložení výsledku do
registru Rx.
Ve všech těchto instrukcích musí být registry mezi R16 a R31! Chcete-li používat tyto
instrukce, musíte si vybrat některý z těchto registrů pro použití těmito instrukcemi. Tím se
zjednoduší programování. To je dalším důvodem proč používat direktivu definující jméno
registru, protože se snadněji dá měnit používání registrů.
Registry - ukazatele
Velmi zvláštní úlohu mají dvojice registrů R26:R27, R28:R29 a R30:R31.Důležitost těchto
dvojic registru je podtržena tím, že mají zvláštní jména v assembleru: X, Y a Z. Tyto dvojice
jsou 16-bitové registry - ukazatele, schopné ukazovat na adresy s max. 16-bity v paměti
SRAM (X, Y nebo Z) nebo v programové paměti (Z).
Dolní byt 16-bitové adresy je umístěn v dolním registru, horní byt v horním registru. Obě
části mají svá vlastní jména tj. vyšší byt ze Z je pojmenován ZH (=R31), dolní byt je ZL
(=R30). Tato jména jsou definována ve standardních hlavičkových souborech pro MCU .
Rozdělení těchto 16-bitových ukazatelů do dvou různých bytů se dá udělat třeba takto :
.EQU Adress = RAMEND ; RAMEND je nejvyšší 16-bitová adresa v SRAM
LDI YH,HIGH(Adress) ; nastaví MSB
LDI YL,LOW(Adress) ; nastaví LSB
Přístup prostřednictvím ukazatelů se programuje pomocí specielně navržených instrukcí. Ke
čtení se využívá LD (LoaD), pro zápis ST (STore), např. s ukazatelem X ( X-pointer):
ukazatel popis příklad
X Zápis/čtení z adresy X, ukazatel se nemění LD R1,X
Učební materiál ASM AVR
10
ST X,R1
X+ Zápis/čtení z adresy X a poté inkrementace ukazatele o 1 LD R1,X+
ST X+,R1
-X Dekrementace ukazatele o 1 a pak zápis/čtení z nové adresy LD R1,-X
ST -X,R1
Obdobně můžeme používat i Y a Z.
Existuje pouze jedna instrukce pro čtení z programové paměti. Je definovaná pro
ukazatelovou dvojici Z a jmenuje se LPM (Load from Program Memory). Tato instrukce
kopíruje byt na adrese Z v programové paměti do registru R0. Protože programová paměť je
slovově organizována (jedna instrukce na jedné adrese je složená z 16 bitů nebo dvou bytů
nebo jednoho slova) nejméně významný bit vybírá dolní nebo horní byt (0=dolní byt, 1=
horní byt). Z tohoto důvodu původní adresa musí být násobena 2 a přístup je omezen na 15-
bitů neboli 32 kB programovou paměť. Např.:
LDI ZH,HIGH(2*Adress)
LDI ZL,LOW(2*Adress)
LPM
Po těchto příkazech musí následovat inkrementace adresy, aby bylo možné přistupovat
k následujícímu bytu v programové paměti. Protože tento případ nastává dosti často, je kvůli
tomu definována specielní instrukce inkrementující ukazatel, aby mohla být takto použita:
ADIW ZL,1
LPM
ADIW znamená ADd Immediate Word (přičíst konstantu), tato konstanta může být
maximálně 63. Assembler akceptuje dolní část ukazatele, registrové dvojice, ZL jako první
parametr To je poněkud matoucí protože sčítání je realizováno jako 16-bitová operace.
Instrukce doplňku, odečtení konstantní hodnoty mezi 0 a 63 od 16-bitového registrového
ukazatele se jmenuje SBIW, Subtract Immediate Word. (SuBtract Immediate Word). ADIW a
SBIW jsou možné pro ukazatelové registrové dvojice X, Y a Z a pro registrovou dvojici
R25:R24, která nemá specielní jméno a neumožňuje přístup k SRAM nebo programové
paměti. R25:R24 je ideální pro manipulaci s 16-bitovými hodnotami.
Specielním případem užití registrových ukazatelů je přístup k samotným registrům. Registry
jsou umístěny v prvních 32 bytech adresového prostoru MCU (na adresách 0x0000 až
0x001F). Tento přístup má význam pouze když máme kopírovat obsah registrů do SRAM
nebo EEPROM nebo číst odtud hodnoty nazpět do registrů.
Častější užití ukazatelů je přístup k tabulkám s pevnými hodnotami v prostoru programové
paměti. Ukažme si to na následujícím příkladu, kdy máme tabulku s 10ti různými 16-bitovými
hodnotami, kde pátá hodnota z tabulky je čtena do R25:R24:
Učební materiál ASM AVR
11
MojeTabulka:
.DW 0x1234,0x2345,0x3456,0x4568,0x5678 ; tabulka hodnot, slovově
.DW 0x6789,0x789A,0x89AB,0x9ABC,0xABCD ; organizovaná
Read5: LDI ZH,HIGH(MojeTabulka*2) ; adresa tabulky uložená do ukazatele
Z
LDI ZL,LOW(MojeTabulka*2) ; násobená 2ma pro přístup po slovech
ADIW ZL,10 ; ukazuje na pátou hodnotu v tabulce
LPM ; čte nejméně významný byt z programové paměti
MOV R24,R0 ; kopíruje LSB do 16-bitového registru
ADIW ZL,1 ; ukazuje na MSB v programové paměti
LPM ; čte MSB tabulkové hodnoty
MOV R25,R0 ; kopíruje MSB do 16-bitového registru
Toto byl pouze cvičný příklad. Můžete spočítat adresu tabulky v Z z nějaké vstupní hodnoty,
vedoucí na příslušnou tabulkovou hodnotu. Tabulky mohou být také organizovány po bytech
nebo znakově.
Používání registrů - souhrn
1. Definujeme jména registrů pomocí direktivy .DEF , nepoužíváme přímé pojmenování
Rx.
2. Potřebujeme-li přístup pomocí ukazatelů, používáme R26 až R31 .
3. 16-bitový čítač je nejlépe umístit do R25:R24.
4. Když chceme číst z programové paměti, např. pevné tabulky, vyhradíme si Z
(R31:R30) a R0 pro tento účel.
5. Předpokládáme-li přístup k jednotlivým bitům v nějakých registrech (např. při
testování návěští), použijeme pro tento účel R16 až R23 .
Porty procesorů AVR
I/O porty u AVR MCU jsou brány mezi CPU a interními či externími hardwarovými a
softwarovými komponentami. CPU komunikuje s těmito komponentami, čte z nich nebo do
nich zapisuje, jako např. do časovačů nebo paralelních portů. Nejpoužívanějším I/O portem
je stavový registr, kam se zapisují návěští (flagy) závislé na výsledcích předchozích operací a
odkud se čtou podmínky skoků.
Existuje 64 různých I/O portů, které však nejsou fyzicky přítomné ve všech různých AVR
typech. V závislosti na paměťovém prostoru a dalším vnitřním hardware jsou či nejsou
k dispozici různé I/O porty. Konkrétní seznam těchto I/O portů najdeme v katalogových
listech ( data sheets) pro příslušný typ MCU.
Porty mají pevně přidělené adresy, pomocí nichž CPU komunikuje. Tyto adresy jsou
nezávislé na typu AVR. Tak např. port B má vždy adresu 0x18 (0x znamená hexadecimální
notaci). Není nutné si pamatovat tyto adresy, mají vhodná pojmenování . Tato jména jsou
definována v hlavičkových souborech pro různé typy AVR .Tyto soubory jsou vytvořené
přímo výrobcem AVR ATMEL. Hlavičkové soubory obsahují řádek kódu definující adresu
portu B takto:
Učební materiál ASM AVR
12
.EQU PORTB, 0x18
Takže si můžeme pamatovat jen jméno portu B a nikoli jeho umístění v I/O prostoru MCU.
Hlavičkový soubor m8515def.inc se připojí pomocí direktivy assembleru
.INCLUDE "C:\nejaka_cesta\8515def.inc"
a všechny registry obvodu 8515 jsou pak definovány a jsou snadno dostupné.
I/O porty jsou obvykle organizovány jako 8-bitová čísla, ale mohou být jen 8-mi
samostatnými bity, které nemají s ostatními bity nic společného. Mají-li tyto jednotlivé bity
nějaký význam, mají přiděleno své vlastní jméno přiřazené v hlavičkovém souboru, tato
jména např. umožňují manipulaci s jednoduchým bitem. Tato pojmenování umožňuje, že i
v případě samostatných bitů si nemusíme pamatovat pozice bitů. Rovněž tato jména jsou
uvedena v katalogových listech MCU a jsou definována v hlavičkových souborech..
Jako příklad si uvedeme MCUCR ( MCU General Control Register) MCU obecný řídíci
registr,složený z nezávislých samostatných řídících bitů které řídí nastavení obecných
vlastností MCU. Je to I/O port s 8mi řídícími bity majícími svá vlastní jména (ISC00, ISC01,
...). Např. se používají pro uvedení MCU do úsporného SLEEP módu:
.DEF MujRegistr = R16
LDI MujRegistr, 0b00100000
OUT MCUCR, MujRegistr
SLEEP
Instrukce Out přenese obsah mého registru MujRegistr v němž je nastaven Sleep-Enable-
Bit nazvaný SE, do I/O portu MCUCR a nastaví AVR do úsporného režimu, provedením
instrukce SLEEP .
Čtení obsahu I/O portů je v řadě případů možné pomocí instrukce IN . Následující kód
.DEF MujRegistr = R16
IN MujRegistr, MCUCR
čte bity portu MCUCR do registru. Pozn. : u některých portů jsou nedefinované bity , tyto
bity vždy vrací nulu.
Někdy nepotřebujeme čtení všech 8 bitů I/O portu, ale potřebujeme pracovat jen s jedním
bitem portu. V tom případě není nutné číst celý port a pak oddělit jeden bit. Některé instrukce
skoku provádějí svou činnost v závislosti na hodnotě jediného bitu. Nastavení nebo
vynulování jednoho bitu v portu je možné bez čtení a zápisu ostatních bitů portu. Umožňují to
instrukce SBI (Set Bit I/o) a CBI (Clear Bit I/o). Příklad použití :
Učební materiál ASM AVR
13
.EQU ActiveBit=0 ; bit, který se má měnit
SBI PortB, ActiveBit ; tento bit bude nastaven na jedničku
CBI PortB, ActiveBit ; tento bit bude vynulován
Tyto instrukce mají omezení na porty s adresami menšími než 0x20 , k portům na vyšších
adresách nelze takto přistupovat.
Programátorská „finta“: k portům lze přistupovat i pomocí instrukcí pro přístup k SRAM,
např. ST a LD. Proto přičteme 0x20 k adresám portů (prvních 32 adres jsou registry) což nám
umožní přistupovat k I/O portům jako k SRAM. Příklad použití:
.DEF MujRegistr = R16
LDI ZH,HIGH(PORTB+32)
LDI ZL,LOW(PORTB+32)
LD MujRegistr,Z
Pozn. první adresa umístění SRAM je vždy 0x60.
Některé důležité porty u AVR
V následující tabulce jsou uvedeny některé důležité I/O AVR porty. Nejsou zde uvedeny
některé porty řady MEGA
I/O adresa
(SRAM
adresa)
Jméno funkce
$3F($5F) SREG Stavový registr
$3E($5E) SPH Ukazatel zásobníku – vyšší bity
$3D($5D) SPL Ukazatel zásobníku – nižší bity
$3B($5B) GIMSK Mask. Registr vnějších přerušení
$3A($5A) GIFR Registr příznaků vnějších přerušení
$39($59) TIMSK Mask. Registr přerušení čítačů/časovačů
$38($58) TIFR Registr příznaků přerušení čítačů/časovačů
$35($35) MCUCR MCU řídící registr
$34($54) MCUSR MCU stavový registr
$33($53) TCCR0 Řídící registr čítače/časovače 0
$32($52) TCNT0 Čítač/časovač 0 (8 bitů)
$2F($4F) TCCR1A Řídící registr čítače/časovače 1A
$2E($4E) TCCR1B Řídící registr čítače/časovače 1B
$2D($4D) TCNT1H Čítač/časovač 1 – vyšší bity
$2C($4C) TCNT1L Čítač/časovač 1 – nižší bity
$2B($4B) OCR1AH Porovnávací registr čítače/časovače 1A- vyšší bity
$2A($4A) OCR1AL Porovnávací registr čítače/časovače 1A - nižší bity
$29($49) OCR1BH Porovnávací registr čítače/časovače 1B- vyšší bity
$28($48) OCR1BL Porovnávací registr čítače/časovače 1B - nižší bity
$27($47) ICR1H záchytný registr čítače/časovače 1 – vyšší bity
Učební materiál ASM AVR
14
$26($46) ICR1L Záchytný registr čítače/časovače 1 – nižší bity
$25($45) TCCR2 Řídící registr čítače/časovače 2
$24($44) TCNT2 Čítač/časovač 2 (8 bitů)
$23($43) OCR2 Porovnávací registr čítače/časovače 2
$22($42) ASSR Stavový registr asynchronního módu
$21($41) WDTCR Řídící registr časovače watchdog
$1F($3F) EEARH Adresový registr EEPROM – vyšší bity
$1E($3E) EEARL Adresový registr EEPROM – nižší bity
$1D($3D) EEDR Datový registr EEPROM
$1C($3C) EECR Řídící registr EEPROM
$1B($3B) PORTA Datový registr, Port A
$1A($3a) DDRA Směrový registr brány A
$19($39) PINA Vývody brány A
$18($38) PORTB Datový registr, Port B
$17($37) DDRB Směrový registr brány B
$16($36) PINB Vývody brány B
$15($35) PORTC Datový registr, Port C
$14($34) DDRC Směrový registr brány C
$13($33) PINC Vývody brány C
$12($32) PORTD Datový registr, Port D
$11($31) DDRD Směrový registr brány D
$10($30) PIND Vývody brány D
$0F($2F) SPDR Datový I/O registr SPI
$0E($2E) SPSR Stavový registr SPI
$0D($2D) SPCR Řídící registr SPI
$0C($2C) UDR I/O datový registr UART
$0B($2B) USR Stavový registr UART
$0A($2A) UCR Řídící registr UART
$09($29) UBRR Registr rychlostí UART
$08($28) ACSR Řídící a stavový registr analogového komparátoru
$07($27) ADMUX ADC registr výběru multiplexeru
$06($26) ADCSR ADC řídící a stavový registr
$05($25) ADCH ADC datový registr – vyšší bity
$04($24) ADCL ADC datový registr – nižší bity
Stavový registr
Nejpoužívanější I/O port je 8-mi bitový stavový registr. Obvyklý přístup k tomuto registru je
při automatickém nastavování nebo mazání bitů CPU nebo akumulátorem, další přístup je
při čtení jednotlivých bitů při větvení programu. V některých případech se přímo manipuluje
s těmito bity ( použitím příkazů assembleru SEx nebo CLx, kde x je některé z písmen Z,C,
N,V,S,H,T nebo I). Většina těchto bitů je nastavována či mazána akumulátorem při bitových
testech, porovnávání nebo výpočtech. V následující tabulce je uveden seznam
assemblerovských příkazů, které nastavují nebo mažou příslušné bity v závislosti na výsledku
operace.
Učební materiál ASM AVR
15
bit Početní operace Logické
operace
porovnání Bitové
operace
posuny ostatní
Z ADD, ADC,
ADIW, DEC, INC,
SUB, SUBI, SBC,
SBCI, SBIW
AND, ANDI,
OR, ORI, EOR,
COM, NEG,
SBR, CBR
CP, CPC,
CPI
BCLR Z,
BSET Z,
CLZ, SEZ,
TST
ASR,
LSL,
LSR,
ROL,
ROR
CLR
C ADD, ADC,
ADIW, SUB,
SUBI, SBC, SBCI,
SBIW
COM, NEG CP, CPC,
CPI
BCLR C,
BSET C,
CLC, SEC
ASR,
LSL,
LSR,
ROL,
ROR
-
N ADD, ADC,
ADIW, DEC, INC,
SUB, SUBI, SBC,
SBCI, SBIW
AND, ANDI,
OR, ORI, EOR,
COM, NEG,
SBR, CBR
CP, CPC,
CPI
BCLR N,
BSET N,
CLN, SEN,
TST
ASR,
LSL,
LSR,
ROL,
ROR
CLR
V ADD, ADC,
ADIW, DEC, INC,
SUB, SUBI, SBC,
SBCI, SBIW
AND, ANDI,
OR, ORI, EOR,
COM, NEG,
SBR, CBR
CP, CPC,
CPI
BCLR V,
BSET V,
CLV, SEV,
TST
ASR,
LSL,
LSR,
ROL,
ROR
CLR
S SBIW - - BCLR S,
BSET S,
CLS, SES
- -
H ADD, ADC, SUB,
SUBI, SBC, SBCI
NEG CP, CPC,
CPI
BCLR H,
BSET H,
CLH, SEH
- -
T - - - BCLR T,
BSET T,
BST, CLT,
SET
- -
I - - - BCLR I,
BSET I,
CLI, SEI
- RETI
Vstupní/výstupní brány AVR
Vstupní/výstupní brány PORTA, PORTB, PORTC či PORTD (popř. další u AVR MEGA)
umožňují vstup nebo výstup logických signálů do/z MCU. Umožňují přístup bytový i bitový.
Nejprve je však nutné definovat směr přenosu signálů na jednotlivých pinech portu. K tomu
slouží registry DDRA, DDRB, DDRC a DDRD. Pokud chceme, aby byl pin výstupní,
nastavíme příslušný bit v příslušném registru na hodnotu 1. Např. když nastavíme bit 3
v registru DDRB, bude definován pin PB3 jako výstupní.
Pro bitový přístup k portu se využívají dva registry. Pro čtení jednotlivých bitů je určen registr
PINA (PINB, PINC, PIND). Pro přístup k němu používáme např. instrukce SBIS a SBIC
(např. SBIS PINB,3). Pro zápis je určen registr PORTA (PORTB, PORTC, PORTD).
Nastavením jeho jednotlivých bitů se nastavují příslušné piny. Používáme k tomu instrukce
Učební materiál ASM AVR
16
SBI a CBI (např. SBI PORTA, 1). Pro bytový přístup se pro čtení i zápis používají stejné
registry jako při bitovém přístupu, avšak pro čtení a zápis používáme instrukce IN a OUT
(např. IN DATA,PINB ).
Použití SRAM v AVR assembleru
Všechny ATMEL AVR typy MCU (s výjimkou AT90S1200) mají v sobě statickou paměť
RAM (SRAM). Pouze velmi jednoduché assemblerovské programy používají jako paměť
jenom registery. Pokud bude program využívat i SRAM, má k dispozici větší paměťový
prostor.
SRAM
SRAM je paměť, k níž nemá CPU, centrální procesorová jednotka (Aritmetická a Logická
jednotka ALU, někdy nazývaná akumulátor) přímý přístup, na rozdíl od přístupu k registrům.
Pro přístup k buňkám této paměti obvykle používáme registry jako vložené, mezilehlé paměti.
V následujícím příkladu na obrázku bude hodnota z SRAM kopírována do registru R2 (první
instrukce), dále je proveden výpočet nad registry R2 a R3 a výsledek výpočtu je uložen do
R3 (druhá instrukce). Poté je tato hodnota překopírována zpět do buňky SRAM (třetí
instrukce).
Z toho je zřejmé, že operace s hodnotami umístěnými v SRAM jsou pomalejší, než operace
používající jen registry. Na druhé straně i u nejmenších AVR typů majících 128 bytů SRAM,
je to mnohem více, než samotných 32 registrů.
AVR MCU počínajíc typem ATmega8515 mají možnost připojení externí RAM, rozšiřující
vnitřních 512 bytů. Z pohledu assembleru je externí SRAM přístupná stejně jako interní
Učební materiál ASM AVR
17
SRAM. Není potřeba používat nějaké specielní instrukce pro přístup k externí SRAM.
Důvody používání SRAM
Kromě pouhého ukládání hodnot má SRAM další možnosti použití. Kromě možnosti
přístupu s pevnými adresami, se dají používat i ukazatele, takže lze naprogramovat
„plovoucí“ přístup k posloupnosti míst v paměti. Takto můžeme např. naprogramovat i
cyklickou frontu či tabulky. To se nedá udělat se samotnými registry, protože je jich malý
počet a je k nim jen pevný přístup.
Používá se také relativní přístup používající posun (offset) od pevné startovní, počáteční
adresy v jednom z ukazatelových registrů. V tomto případě je pevná adresa uložena
v ukazatelovém registru, konstantní hodnota je přičtena k této adresa a čtení/zápis se provádí
s touto posunutou adresou. Pomocí tohoto postupu se zjednodušuje přístup k tabulkám.
Důležitou aplikací SRAM je tzv. zásobník. Když chceme uložit hodnoty do zásobníku, dáme
nejdříve do registru návratovou hodnotu volajícího podprogramu nebo návratovou adresu
obslužného podprogramu hardwarově spuštěného přerušení.
Ukázky používání SRAM
Při kopírování nějaké hodnoty do nějakého místa v SRAM musíme definovat adresu tohoto
místa. Adresa SRAM může být v rozmezí od 0x0060 (hexa notace)do konce fyzické SRAM
na čipu (v ATmega8515 je nejvyšší adresa ve vnitřní paměti SRAM 0x025F). Pomocí
příkazu
STS 0x0060, R1
je obsah registru R1 kopírován na první místo v SRAM. Pomocí
LDS R1, 0x0060
je obsah SRAM na adrese 0x0060 kopírován do registru. Je to přímý přístup na adresu
definovanou programátorem.
Lze používat symbolická jména pro usnadnění práce s pevnými adresami, která je jinak
obtížná, chceme-li později měnit strukturu dat v SRAM. Manipulace s těmito jmény je
snadnější, než s hexadecimálními čísly, proto dáváme adresám jména
Vloženo: 17.05.2009
Velikost: 1,19 MB
Komentáře
Tento materiál neobsahuje žádné komentáře.
Copyright 2024 unium.cz