Změny běhu programu
Skoky a přeskoky
- nepodmíněné skoky (jumps)- provedení těchto skoků nezávisí na žádné podmínce, provedou se vždy
- podmíněné skoky (branchs) - narozdíl od předchozích se provedou pouze po splnění určité podmínky
- přeskoky (skips) - tyto speciální skoky přeskočí následující intrukci pouze tehdy, je-li splněna podmínka.
Příkládám odkaz na dokument výrobce vysvětlující význam instrukcí. My si je rozebereme podrobněji dále v tomto díle. Než se do toho pustíme, musíme si vysvětlit, jakou úlohu má v procesorech AVR registr SREG.
SREG - STATUS REGISTER
STATUS REGISTER, neboli stavový registr, je jednim z nejdůležitějších registrů procesoru AVR. Především uchovává informace o výsledcích aritmetických, ale i jiných operací (instrukcí).| I | T | H | S | V | N | Z | C |
- indikuje příznak přetečení po jakékoliv matematické operaci (aitmetická, logická)
- nastaví se v případě, že výsledek přechozí operace byl 0
- je nastaven v případě že výsledek matematické operace byl záporný
- určeno pro výpočet druhého doplňku
- znaménko čísla v druhém doplňku (S = N XOR V)
- nastaven v případě, že dojde k přetečení mezi nižší a vyšší polovinou výsledku
- používá se pro kopírování bitu
- globální povolení / zakázání přerušení.
Zásobník
Velmi důležitou součástí každého mikroprocesoru je tzv. zásobník, jde o vyhražené misto v RAM, kam se ukládají uživatelská data, nebo návratové adresy (obsah čítače instrukcí). Zásobník je součástí RAM a proto musí být na začátku programu korektně nastaven, aby se co nejvýše změnila nepravděpodobnost jeho přepsání, které by mohlo mít fatální následky.Zásobník má dvě důležité funkce. Lze do něj uložit dočasně obsahy registrů například při obsluze přerušení, nebo nečekaných voláních. Druhou ale důležitější funkcí je ukládání návratových adres. Když je zavolán podprogram, uloží se do zásobníku aktuální hodnota programového čítače, tedy místo, kde se program aktuálně nachází. Po skončení podprogramu se hodnota ze zásobníku vyjme a běh programu se vrátí zpět na původní místo.
K zásobníku neodmyslitelně patří ukazatel zásobníku (STACK POINTER), jehož obsah přesně určuje, kde v RAM se zásobník nachází. Protože s každým uložením se jeho hodnota snižuje, respktive zvyšuje s každým vyjmutím, je nutné ho na začátku programu nastavit na konec RAM, to se dělá například takto.
LDI R1, LOW (RAMEND)
OUT SPL, R1
LDI R1, HIGH(RAMEND)
OUT SPH, R1
RAMEND je konstanta, která je specifická pro každý typ procesoru a je v ní obsaženo číslo udávající velikost RAM. Z příkladu vyplývá, že ukazatel zásobníku je doubajtové číslo, rozdělené na nižší a vyšší bajt.
Instrukce pro změnu běhu programu
SKOKY- RJMP - nepodmíněný skok
- IJMP - nepodmíněný absolutní nepřímý skok
- BRBS - provede relativní skok, je-li bit s v registru SREG nastaven
- BRBS s, rel
- BRBC - totéž, ale skok se provede když je bit vynulován
- BREQ - provede skok, je-li Z bit ve status registru nastaven - shoda při matematické operaci
- BRNE - opačný případ k předchozímu, využití i při porovnáváni výsledku s nulou
- BRCS - provede relativní skok, je-li C (carry) nastaveno
- BRCC - opačné k předchozímu
- BRLO - provede skok, je-li 1. operand menší než druhý
- BRMI - provede skok, je-li výsledek záporný
- BRPL - provede skok, je-li výsledek kladný
Toto je výčet nejčastěji používaných instrukcí skoků (alespoň v mém případě tomu tak je), ostatní si můžete nalézt ve výše uvedeném dokumentu. Není-li uvedeno jinak, je za instrukcí pouze návěstí.
PŘESKOKY
- CPSE - provede přeskok v případě rovnosti operandů
- CPSE Rd,Rr
- SBRC - přeskočí v případě nulového bitu v registru
- SBRC Rr,b
- SBRS - opačně k předchozímu
- SBIC - přeskočí, je-li vynulován bit b na portu
- SBIC P,b
- SBIS - opačně k předchozímu
Volání
Využití
Využití probrané látky si ukážeme na jednoduchém příkladě. Tento příklad můžete najít v knize od Davida Matouška. Jedná se o běžící světlo. Připojte na port D LED proti napájení a uvidíte sami. Doporučuji tento příklad prokrokovat v AVR Studiu. .NOLIST
.INCLUDE "m16def.inc"
.LIST
.CSEG
.DEF REG=R16
.EQU DDR=DDRC
.EQU PORT=PORTC
LDI REG,$FF
OUT DDR,REG
LDI REG,LOW(RAMEND)
OUT SPL,REG
LDI REG,HIGH(RAMEND)
OUT SPH,REG
CLC
LDI REG,$FF
SMYCKA:
OUT PORT,REG
RCALL CEKEJ
ROL REG
RJMP SMYCKA
;čekací rutina (čeká asi 0,5 s)
CEKEJ:
LDI R17,40
LDI R18,0
LDI R19,0
CEKEJA:
DEC R19
BRNE CEKEJA
DEC R18
BRNE CEKEJA
DEC R17
BRNE CEKEJA
RET
Komentovat článek
Komentáře k článku
Ještě by mě zajímalo, co technikovi vadí na tomto webu tolik, že se do něj opírá při každý přiležitosti... Komu se tu nelíbí, chodit nemusí...
Bohužel diskusní fórum bude z tohoto důvodu zrušeno.
Opravdu pěkná práce. Jen co je pravda. A mohou mi páni tvůrci tohoto webu laskavě vysvětlit, proč je v diskusním fóru míto rad, návodů a řešení debilní porno? Živíte se snad jím?
Díky, není to jen moje práce, dělali sme na tom ve dvou. Zatím je to nedistribuovatelný, protože je to dělaný víceméně na míru tomuhle webu. Uvažovali sme o tom, že bysme to nějak uvolnili k šíření, ale nebyl čas a stále není. Pokud máš ale nějaký dotaz, rádi zodpovíme. Mužeš psát na redakce@kvetakov.net
Pěkná práce, vidím, že s grafikou a PHP to umíš. Pod jakou licencí je ten systém? Pokud je to něco GPL kompatibilní, tak bych to rád někde stáhnul.
To Technik: Díky za připomínku, ale každému asi dojde, že program vykoná až následující instukci... To Ondra: Máme vlastní redakční systém... Dalo to sice trochu práce, ale zas víme, kam šáhnout, když je třeba něco upravit
Jaký používáš redakční systém?
1) Žádná instrukce, která obsahuje 8 bitovou konstantu (např. LDI, CPI, SUBI, ANDI,...), nemůže pracovat s registry R0 až R15. Takže zápis LDI R1, LOW (RAMEND) bude generovat chybu! 2) RAMEND neurčuje velikost paměti RAM, ale poslední adresu v RAM. Velikost je určena v SRAM_SIZE. 3) "Když je zavolán podprogram, uloží se do zásobníku aktuální hodnota programového čítače, tedy místo, kde se program aktuálně nachází. Po skončení podprogramu se hodnota ze zásobníku vyjme a běh programu se vrátí zpět na původní místo." A na původním místě je volání onoho podprogramu, takže se program zacyklí! Takhle ten zásobník asi nefunguje.
Díky, opraveno
SREG nazev bitu I je spatne, popis je jiz spravne.

