Jste zde

ATMEL AVR neboli mikroprocesory rodiny 90Sxxx a dalších

Miniseriál o mikrokontrolérech ATMEL AVR. V prvním díle se seznámíme s jejich architekturou a

způsoby adresování. Další díly se pak budou zabývat již popisem konkrétních typů mikroprocesorů.

Na úvod trocha historie

V 70. letech minulého století, kdy spatřil světlo světa první mikroprocesor (čtyřbitový I4004) a kdy technologie výroby složitých integrovaných obvodů byla v plenkách, byli návrháři touto technologií omezeni a také jim scházely zkušenosti z použití těchto nových prvků. Spolu se zlepšující se technologií a zkušenostmi z nasazení prvních mikroprocesorů se návrhářům dařilo navrhovat stále lepší obvody. Z nejznámějších jmenujme alespoň Intel 8008 (první 8bitový procesor), legendární Intel 8080, Zilog Z80, Intel 8051, Rockwell 6502 či MOTOROLA 6800.

Spolu s vlastními mikroprocesory začal vývoj prostředků usnadňující vývoj vlastních aplikací a psaní programového vybavení. Zvláště zkušenosti programátorů píšících programy byly velmi důležité, neboť na jejich zkušenostech se měnila struktura a instrukce mikroprocesorů. Optimalizace instrukční sady mikroprocesorů získala na významu v momentu nástupů vyšších programovacích jazyků (PL/M, Pascal a zvláště jazyka C), neboť tyto jazyky umožnily mnohem rychlejší návrh a odladění vlastní aplikace, ale také znamenaly nárůst ceny zařízení, neboť program byl delší a vyžadoval jednak větší, a tudíž dražší paměť, jednak rychlejší mikroprocesor.

Mikroprocesory rodiny 89Cxx, 89Sxx

Když firma ATMEL viděla, jaký úspěch na trhu zaznamenal Intel se svojí rodinou 80C5x, uvedla kolem roku 1993 svoji inovaci tohoto oblíbeného mikroprocesoru. Tou inovací bylo použití paměti Flash jako programové paměti namísto do té doby používané EPROM. I když se to na první pohled nemusí zdát, byl to velmi dobrý tah, neboť do té doby, aby bylo možno do mikroprocesoru nahrát (přeprogramovat) nové programové vybavení, musel být zapouzdřen do velmi drahého keramického pouzdra s okénkem. Po odladění programového vybavení šlo pak pro větší série použít ten samý procesor v laciném plastovém pouzdru, který neměl možnost přeprogramování, neboť pouzdro nemohlo mít okénko nutné pro smazání informace uložené v paměti EPROM pomocí UV záření. Díky velmi dobře zvládnuté technologii Flash slavila firma ATMEL velké úspěchy s tímto mikroprocesorem. To vedlo firmu k uvedení vlastních „odvozenin“ základního typu. Jelikož ne všechny aplikace potřebují tolik vstupů/výstupů, jako má mikroprocesor v pouzdře DIL 40, jako první se objevila na trhu verze v pouzdře DIL20 a to 89C2051 a po ní následovaly další jako např. 89C1051, 89C1051U a 89C4051. Pravděpodobným vzorem těchto mikroprocesorů byl 80C751 firmy, který ale neměl implementovány některé instrukce, což se ukázalo jako velká nevýhoda. Nárůst složitosti aplikací spolu se stále častějším používáním vyšších programovacích jazyků donutily výrobce implementovat do mikroprocesoru stále větší paměť programu a v menší míře i větší paměť dat. Složitější aplikace taktéž vyžadovaly a vyžadují nové a nové periférie. Proto se na trhu objevily další typy, které tyto potřeby uspokojují. Proto v této řadě mikroprocesorů s jádrem 8051 najdeme obvody s integrovaným obvodem Watchdog, analogovým komparátorem, pamětí EEPROM pro konfigurační (kalibrační) data, pamětí programu až 32kB, rozhraním SPI, dvojitým data pointerem. Stručný přehled těchto procesorů je v tab.1.

TypFlashmax. fCPUUccPinůPouzdraPoznámky
AT87F51
4KB
33MHz
5V
40;44
1*
Quick Flash OTP
AT87F51RC
32KB
33MHz
5V
40;44
1*
Quick Flash OTP, dual data pointer
AT87F52
8KB
33MHz
5V
40;44
1*
Quick Flash OTP
AT87F55WD
20KB
33MHz
5V
40;44
1*
Quick Flash OTP, WDT,dual data pointer
AT87LV51
4KB
16MHz
3V
40;44
1*
Quick Flash OTP
AT87LV52
8KB
16MHz
3V
40;44
1*
Quick Flash OTP
AT89C1051U
1KB
24MHz
3V-5V
20
2*
 
AT89C2051
2KB
24MHz
3V-5V
20
2*
 
AT89C4051
4KB
24MHz
3V-5V
20
2*
 
AT89C51
4KB
33MHz
5V
40;44
1*
výroba ukončena -> 89S51
AT89C52
8KB
33MHz
5V
40;44
1*
výroba ukončena -> 89S52
AT89C55WD
20KB
33MHz
5V
40;44
1*
WDT, dual data pointer
AT89LS53
12KB
12MHz
3V-5V
40;44
1*
ISP, SPI
AT89LS8252
8KB
12MHz
3V-5V
40;44
1*
2KB EEPROM, ISP, SPI
AT89LV51
4KB
16MHz
3V-5V
40;44
1*
 
AT89LV52
8KB
16MHz
3V-5V
40;44
1*
 
AT89LV55
20KB
12MHz
3V
44
1*
ISP
AT89S4D12
4KB
12MHz
3V
28;32
SOIC
128KB DataFlash
AT89S51
4KB
24MHz
5V
40;44
1*
Dual data pointer,ISP, následník 89C51
AT89S52
8KB
24MHz
5V
40;44
1*
Dual data pointer,ISP, následník 89C52
AT89S53
12KB
24MHz
5V
40;44
1*
Dual data pointer, ISP, SPI
AT89S8252
8KB
24MHz
5V
40;44
1*
Dual data pointer, 2KB EEPROM, ISP, SPI
AT89C51RC
32KB
33MHz
5V
40;44
1*
Dual data pointer, 512byte XRAM, ISP
Tab.1 - Pouzdra: 1* - PDIP, TQFP, PLCC; 2* - PDIP, SOIC

I když tyto inovace spolu se zlepšující se technologií přinesly zvýšení hodinového kmitočtu procesoru až na 33MHz, a tím zvýšení výpočetního výkonu až na 2.75MIPS, přece jenom potřebám některých aplikací přestaly tyto procesory stačit.

Jelikož o těchto mikroprocesorech bylo napsáno velmi mnoho, nebudu se o nich více rozepisovat a odkazuji čtenáře na jinou literaturu.

Mikroprocesory rodiny AVR

Na začátku 90.let minulého století se skupina norských návrhářů spolu s programátory rozhodla navrhnout novou strukturu mikrokontroléru tak, aby struktura tohoto mikrokontroléru vyhovovala překladačům vyšších programovacích jazyků, zejména široce používaného jazyka C. Výsledkem snažení této skupiny bylo optimalizované jádro nové řady mikroprocesorů s harvardskou architekturou nesoucí hlavní charakteristiky mikroprocesorů s redukovanou instrukční sadou (RISC – Reduced Instruction Set Controllers). Výsledek můžete vidět na obr.1 (konkrétně jde o typ AT90S8414). Přes zdánlivou podobnost s jádrem mikroprocesoru 8051 najdeme zde podstatné odchylky. Především je to šíře instrukčního slova, které je 16bitové. Zvětšení šířky instrukčního slova na jednu stranu zvětšilo požadavky na velikost paměti, na druhou stranu však umožnilo zrychlit načtení mnoha instrukcí, neboť kromě několika výjimek, vystačí instrukce s jedním slovem, tj. mikroprocesor je dokáže načíst během jednoho hodinového cyklu. Druhým viditelným rozdílem je propojení ALU s tzv. polem 32 pracovních registrů. Tato organizace ALU spolu se 16bitovým instrukčním slovem umožnila návrhářům snížit počet hodinových taktů potřebných na provedení téměř všech instrukcí na pouhé dva takty, načtení+dekódování a vykonání. Díky tomu že instrukce vystačí s jedním slovem, to umožnilo implementaci jednoduchého překrývání zmíněných dvou fází. Počet hodinových taktů potřebných na vykonání instrukce typu registr-registr se tímto snížil na pouhý 1 hodinový takt. Srovnáme-li toto se základním instrukčním cyklem řady 80C51, vidíme, že jádro nové řady mikroprocesorů AVR dokáže poskytnout 12x vyšší výpočetní výkon při shodném hodinovém taktu.

Další „vylepšení“ se odehrála při návrhu instrukční sady (vlastních instrukcí mikroprocesoru, které je schopen vykonávat). Tato část byla, jak již bylo řečeno, řešena ve spolupráci s programátory, tvůrci překladačů jazyka C. Velmi důležitou podmínkou pro generování efektivního kódu při překladu je existence data pointerů (datapointerů?). Proto byly do struktury zprvu implementovány dva tyto pointery (registry), pojmenované X a Y. Sama existence těchto registrů/pointerů není postačující k efektivnímu překladu z vyšších programovacích jazyků. Nedílnou součástí je ještě implementace vhodných módů adresování. Analýzou mnoha již napsaných programů byly jako nejvhodnější vybrány následující adresovací módy:

  • nepřímé (indirect addressing)
  • nepřímé s post-inkrementací (indirect with post-increment)
  • nepřímé s pre-dekrementací (indirect with pre-decrement)
  • nepřímé s posunem (indirect with displacement)
  • přímé stránkové adresování (page direct addressing) *

Nyní si stručně popišme jednotlivé způsoby adresování. U nepřímého adresování je hodnota v určeném registru brána jako adresa, na které je uložen operand (hodnota). Stejně je tomu i u dvou následujících adresovacích módů s tím rozdílem, že u prvního dojde po vyzvednutí operandu ke zvětšení hodnoty v registru, tj. adresy operandu, o 1, u druhého je hodnota v příslušném registru nejdříve o 1 zmenšena a pak použita jako adresa operandu. Oba způsoby adresování jsou velmi vhodné při práci s proměnnými delšími než jeden byte, ať už jsou to číselné hodnoty, nebo znakové řetězce (strings). Předposlední způsob adresování je velmi vhodný pro adresování prvků struktury (příkaz struct v jazyce C) a lokálních proměnných v podprogramech. I když instrukční slovo má šířku 16 bit a zdálo se zprvu návrhářům dostatečně dlouhé, zbyly na hodnotu znamenající posunutí pouze 4 bity, což je velmi málo, neboť téměř vždy je potřeba více. Vzhledem k obtížnějšímu používání přímého stránkového adresování, zvolili návrháři mikroprocesoru spolu s návrháři překladače jazyka C cestu zredukování, tj. vynechání, tohoto způsobu adresování. Tím vznikl větší prostor pro hodnotu posunutí, která může být max. 63, což ve většině případů již postačuje (nezapomínejme, na jaké úkoly jsou tyto mikroprocesory předurčeny).

Díky těmto dvěma registrům by bylo možné přesouvat data z jednoho místa (zdroje) na druhé (určení) bez nutnosti manipulace s hodnotou v pointerech (ukazatelích) jako v případě pouze jednoho registru, kde po načtení jednoho byte data musíme zaměnit hodnotu v pointeru ze zdrojové adresy na cílovou a byte dat uložit. Je celkem jasné, že procesor se dvěma pointery přesune data mnohem rychleji. Jelikož však je nutné vytvořit v architektuře mikroprocesoru tzv. zásobník, zabere nám bohužel jeden registr právě realizace tohoto zásobníku. Aby návrháři předešli problémům neefektivního přesunu dat s jedním pointerem, přidali do architektury třetí pointer, sice s omezenými vlastnostmi, ale který je pro přesun dat plně postačující. Takže v architektuře mikroprocesorů najdeme pointery celkem tři pojmenované X, Y a Z. Pro názornost si uveďme příklad přesunu dat z jednoho místa v paměti na druhé:

		LDI	R16,0x60
Loop:
LD	R17,Z+
ST	X+,R17
SUBI	R16,1
BRNE	Loop

Jak je možné i z tohoto jednoduchého příkladu vidět, implementace tohoto úkolu díky dostatečnému počtu pointerů a vhodných způsobech adresování, zde konkrétně post-increment, proběhla velmi efektivně.

Vraťme se nyní k problému vynechaného stránkového adresování. Tento způsob adresování byl nahrazen přímým adresováním s plnou délkou adresy, která je 16bitová. Tento způsob adresování má sice velkou nevýhodu v tom, že vyžaduje, aby instrukce byla dlouhá dvě slova (dvouslovná), přičemž první 16bitové slovo je operační kód instrukce, druhé slovo je 16bitová adresa, ale získáme tím možnost k přístupu k datům o velikosti 64 Kbyte, což pro mnoho aplikací postačuje. Zároveň je tento způsob adresování vhodný pro implementaci datové třídy static, neboť všechny proměnné této třídy musí být umístěny z principu v paměti a ne v registrech. I přes uvedenou nevýhodu velké délky instrukce zůstává tento způsob adresování vhodný pro načítání či úschovu dat typu byte, jak ostatně můžeme vidět z následujícího příkladu (načtení hodnoty proměnné typu char):

Nepřímé adresování

		LDI	R30,Low(CharVar)
LDI	R31,High(CharVar)
LD	R16,Z

Přímé adresování

		LDS	R16,CharVar

Z výše uvedeného je možné vidět, že v prvním případě potřebujeme celkem 6 byte paměti programu (tři slova), kdežto v druhém jen 2 slova paměti programu.
Pro práci s daty o větší šířce, např. typu long integer, který je 32bitový, je vhodnější použití nepřímého adresování

Nepřímé adresování

		LDI	R30,Low(LongVar)
LDI	R31,High(LongVar)
LDD	R0,Z
LDD	R1,Z+1
LDD	R2,Z+2
LDD	R3,Z+3

Přímé adresování

		LDS	R0,LongVar
LDS	R1,LongVar+1
LDS	R2,LongVar+2
LDS	R3,LongVar+3

V případě první varianty je potřeba programové paměti 12 byte, kdežto v případě druhém potřebujeme pro stejnou funkci 16 byte.

Další oblastí, kde došlo k velmi důležité optimalizaci instrukční sady mikroprocesoru, jsou aritmetické operace umožňující práci s daty delšími než 1 byte. Těmito instrukcemi jsou instrukce využívající příznaku Carry, a to konkrétně CPC a SBC. Optimalizace spočívá v odlišném přístupu k nastavování příznaku Z, tj. indikace nulového výsledku. Pro ilustraci si uveďme následující vzorový příklad porovnání dvou 32bitových čísel. První operand je umístěn v registrech R3, R2, R1 a R0, druhý operand je v registrech R7, R6, R5 a R4, přičemž registr R0 a R4 obsahují nejnižší část hodnoty.

		SUB	R0,R4
SBC	R1,R5
SBC	R2,R6
SBC	R3,R7
BREQ	destination

Po provedení porovnání v případě rovnosti obou operandů by měla instrukce BREQ (BRanch if EQual) zajistit pokračování programu na adrese destination. V případě předchozích typů mikroprocesorů však toto není pravda, neboť stav příznaku Zero (Z) závisí pouze na poslední instrukci, tj. pokud jsou nejvyšší byte operandů shodné, provede se skok na adresu destination bez ohledu na výsledky porovnání nižších byte, což je chybná interpretace. Pro korektní funkci tohoto testu bychom museli přidat za každou instrukci SUB či SBI jednu instrukci BRNE (BRanch if Not Equal), která by ukončila porovnání v momentu neshodnosti obou registrů. Výše uvedené „zkomplikování“, nutnost přidat tři skokové instrukce, vede u klasické interpretace příznaku Zero jednak k nárůstu délky programu, jednak k většímu zatížení mikroprocesoru. Jelikož obdobné operace jsou v programech velmi časté, přistoupili návrháři mikroprocesorů k optimalizaci manipulace s příznakem Zero. Řešení spočívá v tom, že operace CPC a SBC mohou příznak Zero pouze resetovat (vynulovat), nikdy ne nastavit. Funkce, která je realizována pro příznak Zero u obou zmíněných funkcí, se dá popsat:

Z = (výsledek==0) AND Zold

Výsledný stav příznaku Zero pak závisí na všech předchozích operacích a nejen na poslední. Z tohoto důvodu bude výše uvedený příklad na nových mikroprocesorech AVR pracovat regulérně, kdežto na standardních mikroprocesorech, jako například 89C51, ne. Chování příznaku Zero u ostatních operací je shodné se standardními mikroprocesory. Chování ostatních příznaků je taktéž shodné se zažitým chováním obdobných příznaků u ostatních mikroprocesorů.

Jelikož funkce rozhodování je velmi často používána v programech, a tudíž záleží velmi na její implementaci, vybavili návrháři mikroprocesor velkým souborem podmíněných skokových instrukcí, které umožňují efektivní testování různých podmínek (stavů).

Závěrem

Tento nový miniseriál bude pokračovat jednotlivým krátkým představováním mikroprocesorů z rodiny AVR, a to včetně vývojových prostředků. Dovolím si upozornit na jednu příjemnou novinku dopředu. Firma ATMEL přichystala pro uživatele nových procesorů ATmega16, ATmega32 či dalších z této řady příjemné překvapení v podobě rozhraní JTAG, které je určeno pro fázi odlaďování programového vybavení. Přes toto rozhraní je možné mikroprocesor v aplikaci plně ovládat, tj. krokovat, měnit jeho program, vyčítat proměnné. Procesor se tedy chová jako emulátor sebe sama. Díky tomuto rozhraní tedy odpadá jindy nutná „bolestivá“ investice do drahého emulátoru.

„Hráčů“ v této kategorii mikroprocesorů je však mnohem více, z nejznámějších jmenujme alespoň ST Microelectronics (bývalý Thomson), MICROCHIP, MOTOROLA, Windbond, Sharp, či ZILOG, přičemž mnoho zajímavých mikroprocesorů vzniká několik do roka. Jako zástupce těchto novinek jmenujme firmu Cygnal (procesory C8051Fxxx, článek v KTE 6/2001 a ST 7/2001) nebo firmu Triscend s jejími klony E5 příp. A7.

Jiří KOPELENT
jiri.kopelent@ gme.cz

Poznámka redakce : Vzhledem k tomu, že úvodní díl tohoto seriálu byl napsán před třemi lety, mohou být některé údaje již zastalé.

DOWNLOAD & Odkazy

Hodnocení článku: