Sunteți pe pagina 1din 218

IOAN BURDA

MICROPROCESOARE
I
MICROCONTROLERE

Presa Universitar Clujean 2002

ii

Moto:

Dac nu voi vedea n minile Lui semnul cuielor, i dac nu voi pune degetul meu n semnul cuielor, i dac nu voi pune mna mea n coasta Lui, nu voi crede.

Ioan 19, 20

iv

1. Utilitarul Debug. Familia de Microprocesore 80X86 2. Programe Simple n Limbaj de Asamblare 3. Circuite Specializate Programabile 4. Portul Paralel. Aplicaii Simple 5. Programe Residente n Memorie 6. Perioada i Frecvena unui Semnal Extern 7. Microcontrolerul 68HC11. PcBug 8. Voltmetru Digital cu Microcontrolerul 68HC11 9. Microcontrolerul PIC 16F84 A. Setul de Instruciuni al Familiei de Microprocesoare 80X86 B. Setul de Instruciuni ale Microcontrolerului 68HC11

7 19 37 59 87 105 127 161 179 197 211 217

C. Setul de instruciuni ale Microcontrolerului PIC 16F84

vi

Microprocesoare i Microcontrolere

1. Utilitarul DEBUG. Familia de Microprocesoare 80X86

Aceast carte este scris n "viu grai" cu scopul de a permite unui "simplu cetean" accesul la bazele unui domeniu de mare complexitate i actualitate. Omul, n evoluia sa, a fost preocupat de realizarea unor unelte cu ajutorul crora activitatea de zi cu zi s devin mai eficient. De la primele pietre oferite de natur sau prelucrate sumar i pn la sistemele cu microprocesor ncorporat (embedded system) din zilele noastre este un timp att de lung, nct istoria nu-l poate cuprinde. Astzi nu putem s ne imaginm existena fr aceast complex unealt. Dar n acelai timp, nu putem s nu ne punem ntrebri de forma: "Ci dintre oamenii care au cltorit cu trenul pot proiecta sau construi o locomotiv ?" sau "Ci dintre oamenii care zboar cu avionul pot proiecta sau construi un avion ?". Din pcate, lucrul acesta este valabil i n aceast situaie i chiar mai mult, s nu uitm c de data aceasta avem n fa cea mai complex i abstract unealt imaginat de mintea omului. Atunci cnd vrei ca oamenii s poat nelege uor un material trebuie s simplifici lucrurile, uneori poate prea mult. Temele care vor fi prezentate n aceast carte au fost selectionate pentru a acoperi o cultur minim n domeniul embedded system i n acelai timp cu gndul la cel care n final va lucra ntr-un domeniu experimental al fizicii. Tocmai de aceea, n locul unor tabele aride din care poi afla multe dar nu nvei nimic, am preferat "graiul viu" desigur, mai puin exact, dar specific omului. Toat informaia de care avem nevoie pentru realizarea aplicaiilor din aceast carte este coninut n embedded system-ul studiat. Din pcate, nu toi oamenii au abilitatea s descopere singuri informaile de care au nevoie i mult prea muli cred c singura metod este nvatul pe de rost a tot felul de situaii particulare. Nimeni nu poate obine performane reale n domeniul embedded system fr un efort individual i liber asumat. Trebuie s ne punem imaginaia la lucru, s ncercm, s fim creativi. Fr a exclude calitile native ale fiecruia, performanele obinute vor depinde n mare msur de numrul de ore de lucru la calculator. n final, vom atinge nivelul de novice n domeniul embedded system printr-un antrenament prelungit care, pentru unii dintre noi, din pcate va fi epuizant. Cu ajutorul unor programe utilitare, vom descoperi o mare parte din secretele sistemelor cu microprocesor ncorporat i modul n care pot fi utilizate n domeniile experimentale. Prin aceast metod ne vom apropia, pas cu pas, de stadiul de novice n domeniul embedded system.

Utilitarul DEBUG. Familia de Microprocesoare 80X86

DEBUG este un program utilitar al sistemului de operare (MS-DOS, Windows xxxx) dintr-un calculator compatibil IBM PC. Accesul la un calculator compatibil IBM PC prin care s "hoinrim" la fel ca ntr-un ora, asigur caracterul interactiv al metodei propuse. De la prompterul MS-DOS (START > PROGRAMS > MS-DOS Prompt),
C:\WINDOWS>

lansm n execuie utilitarul DEBUG.


C:\WINDOWS>debug

Dac prin comanda anterioar obinem prompterul -, atunci utilitarul DEBUG a fost lansat n execuie de ctre sistemul de operare. Prin comanda ? (help), listm comenzile utilitarului DEBUG.
-? assemble A [address] compare C range address dump D [range] enter E address [list] fill F range list go G [=address] [addresses] hex H value1 value2 input I port load L [address] [drive] [firstsector] [number] move M range address name N [pathname] [arglist] output O port byte proceed P [=address] [number] quit Q register R [register] search S range list trace T [=address] [value] unassemble U [range] write W [address] [drive] [firstsector] [number] allocate expanded memory XA [#pages] deallocate expanded memory XD [handle] map expanded memory pages XM [Lpage] [Ppage] [handle] display expanded memory status XS -

Nu ne grbim s le memorm; acum tim cum le putem afla. Cred c cea mai util comand n acest moment este q (quit, abandonm programul utilitar DEBUG). Aa c tastm comanda
-q

Microprocesoare i Microcontrolere i ne rentoarcem la prompterul MS-DOS.


C:\WINDOWS>

Pentru ca aventura s se ncheie n Windows, vom tasta n continuare urmtoarea comand.


C:\WINDOWS>exit

Cu ajutorul editorului NOTEPAD (START > PROGRAMS > ACCESSORIES > NOTEPAD), putem realiza un fiier text, pe care vom face n continuare cteva experiene. Acest fiier fr a conine tasta "Enter" va avea urmtorul coninut:
!"#$%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz {|}~

Fiierul va fi salvat cu numele ASCII.TXT n folderul (directorul) Mm (creat de noi, New - Folder) de pe unitatea C:. Lansm n execuie utilitarul DEBUG. De la prompterul MS-DOS tastm comanda
C:\WINDOWS>cd..

(Change Directory), numai dac nu suntem n directorul rdcin (acest lucru depinde de configurarea sistemului de operare), de unde trecem n directorul Mm prin urmtoarea comand:
C:\>cd mm

Obinem un prompter MS-DOS de forma


C:\Mm>

de unde vom lansa n execuie utilitarul DEBUG. Introducem urmtoarele comenzi


-nascii.txt -l

n continuare

care vor determina ncrcarea fiierului cu numele ASCII.TXT undeva n memoria intern a calculatorului. Dac tastm comanda
-d

10

Utilitarul DEBUG. Familia de Microprocesoare 80X86

putem vedea unde a fost ncrcat fiierul n memoria calculatorului i mai ales sub ce form. Efectul comenzii anterioare este afiarea coninutului unei zone de memorie.
1371:0100 1371:0110 1371:0120 1371:0130 1371:0140 1371:0150 1371:0160 1371:0170 21 31 41 51 61 71 D8 75 22 32 42 52 62 72 02 02 23 33 43 53 63 73 3A 88 24 34 44 54 64 74 06 04 25 35 45 55 65 75 94 89 26 36 46 56 66 76 D2 36 27 37 47 57 67 77 75 6B 28-29 38-39 48-49 58-59 68-69 78-79 C9-4E D7-89 2A 3A 4A 5A 6A 7A 32 0E 2B 3B 4B 5B 6B 7B C0 69 2C 3C 4C 5C 6C 7C 86 D7 2D 3D 4D 5D 6D 7D 04 C3 2E 3E 4E 5E 6E 7E 46 BE 2F 3F 4F 5F 6F 0E 3C 48 30 40 50 60 70 A7 0D DB !"#$%&'()*+,-./0 123456789:;<=>?@ ABCDEFGHIJKLMNOP QRSTUVWXYZ[\]^_` abcdefghijklmnop qrstuvwxyz{|}~.. ..:...u.N2...F<. u....6k...i...H.

Observm c zona de memorie afiat pe ecran conine n totalitate fiierul ASCII.TXT. Pentru realizarea experimentelor din primele ase capitole ale acestei cri, cea mai frecvent aciune este lansarea n execuie a utilitarului DEBUG.

Figura 1.1. Mediu de lucru tipic pentru primele ase capitole ale crii.

Microprocesoare i Microcontrolere

11

Dup cum se poate vedea n figura 1.1, de regul lansarea n execuie este precedat de fixarea directorului utilizat (directorul C:\Mm>), prin intermediul unor comenzi specifice sistemului de operare MS-DOS. S nu intrm n panic, acesta este doar nceputul. Mai trziu, vom rde de inocena noastr de acum. Nu putem nelege totul de la nceput, unele lucruri le vom nelege mai trziu (altele niciodat). S ne ndreptm atenia spre grupul de cifre 1371:0100 (pe un alt calculator este foarte probabil s fie afiat altceva n loc de 1371), probabil suntem ntr-un ora, pe strada 1371 n dreptul casei cu numrul 0100 (atenie, totul este n cod hexazecimal, 00, 01,,09, 0A, , 0F, 10, 11,, 1F, 20, 21,, FF, 100, 101,, FFF, 1000, 1001,, 1FFF , 2000, 2001, , FFFF). Este uor de observat c numrul maxim al unei case pe o strad este FFFFh (h, de la hexazecimal, dac facem conversia n zecimal n total pot fi 65536 de case pe o strad). Coninutul casei cu numrul 100h de pe strada cu numrul 1371h este numrul 21h, care dup cum se poate vedea n zona din partea dreapt a ecranului, este codul caracterului !. Numere despre numere, care ne spun unde se afl alte numere, am ajuns ntr-un ora de numere. Vom spune c 21h este codul ASCII (American Standard Code for Information Interchange) al caracterului !. De exemplu, codul ASCII al caracterului A, este 41h, iar al caracterului a este 61h. Dac privim cu atenie, putem descoperi i o regul: diferena ntre literele mari i cele mici este 20h. Aa c, dac ne mai amintim alfabetul pe care l-am nvaat n primul an de coal, nu mai trebuie s reinem dect numrul 41h. Caracterele asociate numerelor (0, 1, 2, , 9) sunt codate ncepnd cu 0, care are codul 30h. Caracterele care au codul mai mic de 20h (20h este codul pentru SPACE) sunt caractere de control. Acestea sunt de regul, netipribile (le vom relua mai trziu), aa c ele sunt automat nlocuite cu . de ctre utilitarul DEBUG. Forma caracterelor care au codul mai mare de 7Fh depinde n mare msur de o aplicaie concret. nainte de a merge mai departe, s comprimm observaiile anterioare, printr-o exprimare adecvat. Caracterul ! are codul ASCII 21h i n exemplul nostru este nscris n locaia de memorie cu adresa offset 100h aflat n segmentul de memorie cu adresa 1371h. Dup cum se poate vedea, cineva (sistemul de operare) a alocat pentru fiierul nostru segmentul de memorie care ncepe la adresa 1371h. Zona de memorie care nu a fost afectat de ncrcarea fiierului nostru i-a pstrat nealterat vechiul coninut. n aceast zon vom observa cu siguran unele caractere netipribile care au fost nlocuite prin caracterul .. Nu vom merge mai departe pn nu vom arunca o privire n zona de copyright a memoriei ROM BIOS (Basic Input Output System),

12

Utilitarul DEBUG. Familia de Microprocesoare 80X86

unde sunt stocate subprograme. Acestea asigur serviciile de baz legate de funcionarea ntregului sistem, adic utilitile de la marginea oraului de numere. Prin tastarea urmtoarelor comenzi (vom gsi indicatorul de la intrarea ipoteticului ora)
-d f000:e000 F000:E000 00 F000:E010 4D F000:E020 20 F000:E030 41 F000:E040 6E F000:E050 41 F000:E060 1B F000:E070 49 -d F000:E080 EC F000:E090 2C F000:E0A0 39 F000:E0B0 66 F000:E0C0 4E F000:E0D0 31 F000:E0E0 20 F000:E0F0 00 77 20 42 77 63 77 41 4F 35 43 38 74 35 2F 46 00 61 43 49 61 2E 03 77 53 EC 6F 34 77 53 31 4F 00 72 4F 4F 72 6F 0C 61 20 38 70 2D 61 56 31 52 00 64 4D 53 64 66 04 72 76 EC 79 39 72 41 2F 20 00 20 50 20 20 74 01 64 34 3C 72 37 65 20 39 53 00 53 41 43 53 77 01 20 2E EC 69 2C 2C 52 37 41 00 6F-66 54-49 4F-50 6F-66 61-72 6F-66 4D-6F 35-31 41-EC 67-68 20-41 20-49 45-56 29-00 4C-45 00-00 74 42 59 74 65 74 64 50 47 74 77 6E 3A 4D 00 00 77 4C 52 77 20 77 75 47 EC 20 61 63 31 20 00 00 61 45 49 61 49 E9 6C 00 4E 28 72 2E 2E 2D 00 00 72 20 47 72 6E 12 61 DB EC 43 64 00 32 20 00 00 65 34 48 65 63 14 72 32 77 29 20 74 20 4E 00 00 49 38 54 20 2E 20 20 EC 61 20 53 77 28 4F 00 00 42 36 20 49 20 43 42 33 72 31 6F 61 31 54 00 00 .ward SoftwareIB M COMPATIBLE 486 BIOS COPYRIGHT Award Software I nc.oftware Inc. Aw.....oftw... C .Award Modular B IOS v4.51PG..2.3 .5.8.<.A.G.N.war ,Copyright (C) 1 984-97, Award So ftware, Inc..twa N5SVA REV:1.2 (1 1/11/97).M - NOT FOR SALE....... ................

Pe un alt calculator vor fi afiate pe ecran alte informaii. Aa au aprut calculatoarele compatibile IBM PC. Acum ne putem considera rtcii, aa c, cel mai indicat este s tastm comanda q. Prompterul MS-DOS
C:\mm>

este locul unde ne vom ntoarce dup fiecare incursiune (vom afla mai trziu de ce) n ipoteticul ora de numere. Lansm din nou n execuie utilitarul DEBUG i ncrcm n memorie fiierul ASCII.TXT. Afim pe ecran coninutul memoriei unde a fost ncrcat fiierul cu ajutorul comenzii d. De la prompterul utilitarului DEBUG tastm urmtoarele linii de comand:
-e 100 "Nu -d 100 1371:0100 1371:0110 1371:0120 1371:0130 1371:0140 1371:0150 1371:0160 1371:0170 cred ca acest curs o sa-mi influenteze modul de a gindi." 4E 20 66 64 61 71 D8 75 75 63 6C 65 62 72 02 02 20 75 75 20 63 73 3A 88 63 72 65 61 64 74 06 04 72 73 6E 20 65 75 94 89 65 20 74 67 66 76 D2 36 64 6F 65 69 67 77 75 6B 20-63 20-73 7A-65 6E-64 68-69 78-79 C9-4E D7-89 61 61 20 69 6A 7A 32 0E 20 2D 6D 2E 6B 7B C0 69 61 6D 6F 5C 6C 7C 86 D7 63 69 64 5D 6D 7D 04 C3 65 20 75 5E 6E 7E 46 BE 73 69 6C 5F 6F 0E 3C 48 74 6E 20 60 70 A7 0D DB Nu cred ca acest curs o sa-mi in fluenteze modul de a gindi.\]^_` abcdefghijklmnop qrstuvwxyz{|}~.. ..:...u.N2...F<. u....6k...i...H.

Microprocesoare i Microcontrolere
-

13

Astfel am nvat un procedeu de a introduce date n memorie, respectiv de a vedea ce i unde am introdus. Vom tasta n continuare
-w Writing 0005E bytes -q

i ajungem la locul de plecare, prompterul MS-DOS. Cu ajutorul editorului NOTEPAD redeschidem fiierul ASCII.TXT.
Nu cred ca acest curs o sa-mi influenteze modul de a gindi. \]^_`abcdefghijklmnopqrstuvwxyz{|}~

Este uor acum de neles efectul comenzii w (write) a utilitarului DEBUG. n acest moment, nu putem spune dect c este mult mai comod s ne jucm cu mouse-ul n Windows xxxx. Dac noi suntem hotri s atingem nivelul de novice n domeniul embedded system, atunci trebuie s ne ntoarcem la prompterul MS-DOS, de unde s lansm n execuie utilitarul DEBUG. De la prompterul - tastm comanda
-r AX=0000 BX=0000 DS=1371 ES=1371 1371:0100 4E CX=0000 DX=0000 SS=1371 CS=1371 DEC SI SP=FFEE IP=0100 BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

i am ajuns direct pe "biroul primarului" (primarul oraului de numere). Este momentul s vedem ce are pe birou, sau cu alte cuvinte, care sunt i ce semnificaie au regitrii i bistabilii de condiie ai microprocesorului (este vorba de un microprocesor 80X86, sau "Pentium " produs de firma Intel, eventual un alt microprocesor compatibil cu unul dintre acestea produs de o alt firm). Singurele sarcini pe care le execut un microprocesor sunt cele transmise printr-un program. Programul este alctuit dintr-o succesiune de instruciuni (comenzi date microprocesorului) care au drept scop obinerea unui rezultat util. n reprezentare intern, instruciunile sunt un numr binar sau o succesiune de numere binare (compactizate n hexazecimal de utilitarul DEBUG, pentru economia scrierii). Instruciunile formeaz un program n cod-main, dac executarea lor de ctre microprocesor duce la rezolvarea unei anumite probleme. Trebuie menionat c utilitarul DEBUG ne ascunde multe din particularitile microprocesorului pe care l avem pe placa de baz (Mother Board), iar modul de lucru al microprocesorului este implicit cel REAL (un microprocesor din familia amintit cu X > 2 poate lucra n unul din modurile: REAL, PROTEJAT,

14

Utilitarul DEBUG. Familia de Microprocesoare 80X86

VIRTUAL 8086). Limitrile aduse de utilitarul DEBUG nu ne mpiedic s atingem nivelul propus anterior, cel de novice. Regitrii microprocesorului sunt, de fapt, un alt fel de locaii de memorie (care se afl n interiorul microprocesorului), mult mai uor de invocat de programator, deoarece fiecare are un nume (nu o adres). Vom analiza setul de regitrii ai microprocesoarelor din familia 80X86, n limita a ceea ce vedem efectiv prin intermediul utilitarului DEBUG, fr a insista la acest nivel asupra excepiilor fr numr (blestemul compatibilitii de sus n jos al microprocesoarelor Intel). Microprocesoarele din familia 80X86 au patru regitri de uz general, acetia sunt cel mai des utilizai. Fiecare registru de uz general poate fi accesat ca doi regitrii de 8 bii (coninutul acestora este un numr ntre 00h i FFh) sau ca un singur registru de 16 bii (coninutul acestuia este un numr ntre 0000h i FFFFh). Acumulatorul (AH - AL, AX) are un regim privilegiat i este intens folosit de majoritatea instruciunilor. Registrul de baz (BH - BL, BX) poate fi folosit n calcule de adrese de memorie. Registrul numrtor (CH - CL, CX) este invocat cu rol de contor n instruciunile repetitive i de ciclare. Registrul de date (DH - DL, DX) conine adresa de port pentru instruciunile de intrare/ieire (I/O) sau este folosit n instruciunile de nmulire/mprire. Dup cum se poate vedea, coninutul acestora este numrul 0000h i nu se modific n timp. Cu alte cuvinte, utilitarul DEBUG ne creaz impresia c microprocesorul este numai la dispoziia noastr. Microprocesoarele din familia 80X86 (Intel) au patru regitri speciali de 16 bii, doi regitri pointeri i doi regitri index. Indicatorul de stiv (Stack Pointer, SP) permite implementarea stivei n memoria principal i este corelat cu registrul de adres SS. Pointer-ul de baz (Base Pointer, BP) permite accesul la date n regim de stiv. Index-ul surs (SI) i index-ul destinaie (DI) sunt utilizai pentru accesul la date, n special n instruciunile de operaii pe iruri. Limitrile tehnologice din anul 1977 (8086 Intel, primul microprocesor de 16 bii) i experiena anterioar a proiectanilor cu microprocesoarele de 8 bii au generat o structur complex cu cinci regitri de adres, dintre care patru de segment. Regitrii de segment sunt folosii n toate calculele de adrese. Fiecare segment definete un bloc de memorie de 64 Kbyte n cadrul unui spaiu de adres de 1 Mbyte. Segmentul de cod (Code Segment, CS) utilizat n calculul adresei urmtoarei instruciuni de executat lucreaz n conjuncie cu IP. Adresa instruciunii ce urmeaz a se executa se afl la adresa fizic add_mem = [CS]*16 + [IP], unde prin [CS] i [IP] nelegem coninutul acestor regitri. Segmentul de date (Data Segment, DS) este utilizat n general pentru referirile la memorie, aflarea operanzilor i depunerea rezultatelor (sunt cteva excepii pe care le vom vedea cnd vom aborda modurile de adresare ale memoriei). Segmentul de stiv (Stack

Microprocesoare i Microcontrolere

15

Segment, SS) este implicat n toate referirile la memorie care utilizeaz SP i BP. Acestea sunt relative la SS, adic adresa se calculeaz considernd ca segment coninutul registrului SS. Segmentul suplimentar (Extra Segment, ES) conine adresa de segment a unui segment de memorie suplimentar. Pointer-ul de instruciuni (Instruction Pointer, IP) conine adresa curent de offset a instruciunii urmtoare ce urmeaz a fi executat n cadrul segmentului de cod. Cteva precizri se impun nainte de a merge mai departe. Dup cum se poate observa n exemplul prezentat, coninutul regitrilor de segment este acelai 1371h, iar registrul IP conine adresa offset 100h. Reinem c un program de aplicaie n care regitrii de segment deschid acelai segment de memorie, ca i n acest caz, este un program executabil de tip ".COM", iar dac sunt deschise cel puin dou segmente de memorie (eventual suprapuse parial), atunci programul este de tip ".EXE". n cazul nostru, n mod implicit (default) utilitarul DEBUG este pregtit pentru realizarea unui eventual program de aplicaie de tip ".COM". Bistabilii de condiie (flag-uri) sunt grupai ntr-un registru de 16 bii (sau 32 de bii, pentru X > 2). Numai 8 flag-uri sunt afiate de utilitarul DEBUG. Limitarea este generat de modul REAL n care lucreaz microprocesorul i evident de omniprezenta compatibilitate. Trebuie reinut semnificaia acestor flag-uri, deoarece toate deciziile din programele pe care le vom scrie vor depinde de starea acestora. Utilitarul DEBUG afieaz flag-urile ntr-o form abreviat. De la stnga la dreapta este afiat pe ecran starea urmtoarelor flag-uri:
overflow (OF), indic o depire n aritmetica cu semn, NV No oVerflow, OV OVerflow occurred, direction (DF), n cazul operaiilor pe iruri; regitrii SI, DI sunt incrementai sau decrementai, UP Direction is UP, DN direction is DowN, interrupt (IF), activeaz sau dezactiveaz ntreruperile, DI Interrupts are Disabled, EI Interrupts are Enabled, sign (SF), indic semnul rezultatului unei instruciuni, PL Positive sign, NG NeGative sign, zero (ZF), dac rezultatul unei operaii este zero binar se poziioneaz pe starea de adevr, NZ result was Not Zero, ZR result was ZeRo, auxiliary carry (AF), indic apariia unui transport auxiliar, NA No Auxiliary carry, AC Auxiliary Carry, sau mprumut

parity (PF), indic dac numrul de bii poziionai n 1 ai rezultatului este par, PO Parity Odd, PE Parity Even i carry (CF), indic apariia unui transport sau mprumut, NC No Carry, CY - CarrY.

Numai cu titlu informativ, putem spune c, pentru microprocesoarele cu X > 2 regitrii sunt de 32 de bii. Avem aadar urmtoarele abrevieri pentru acetia: EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP. Au fost suplimentai de

16

Utilitarul DEBUG. Familia de Microprocesoare 80X86

asemenea regitrii i/sau bistabilii de condiie (flag-urile) i modurile de organizare a memoriei au fost diversificate. Principiul compatibilitii asigur funcionarea utilitarului DEBUG pentru oricare din membri familiei de microprocesoare 80X86. Ultima linie afiat ne arat ce ar urma s execute microprocesorul dac ar interpreta instruciunea de la adresa offset 100h. n acest caz, opcod-ul (operation code) instruciunii este 4Eh i este tradus de utilitarul DEBUG sub forma DEC SI (DECrementeaz coninutul registrului SI). Trebuie s facem de la bun nceput o precizare: dup cum se poate vedea, instruciunea pentru microprocesor este un opcod (exprimat pe un numr de octei). Pentru a nu fi obligai s reinem aceste opcod-uri, utilitarul ne sugereaz aciunea instruciunilor printr-un mnemonic (reprezentare simbolic pentru instruciune). Aa c, prin termenul de instruciune vom nelege simultan ambele reprezentri, una intern pentru microprocesor (sub form de opcod) i una extern pentru programator, care sugereaz aciunea microprocesorului. Dar mai bine s nu ne aventurm. Tastm n continuare urmtoarele comenzi:
-nascii.txt -l -r AX=0000 BX=0000 DS=1371 ES=1371 1371:0100 4E -

CX=005E DX=0000 SS=1371 CS=1371 DEC SI

SP=FFEE IP=0100

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

i ne ndreptm atenia asupra coninutului registrului CX. Lungimea fiierului ASCII.TXT este 005Eh, dup cum rezult din comanda w (Writing 0005E bytes) anterioar. Este bine s reinem semnificaia registrului CX n raport cu operaiile de citire i/sau scriere ale fiierelor, pe un suport extern de memorie. n acest moment tim suficiente comenzi pentru a crea cu ajutorul utilitarului DEBUG un mic fiier pe care l vom numi HELLO.TXT. Vom tasta n continuare urmtoarele comenzi:
-nhello.txt -e 100 "Hello -d 1371:0100 48 1371:0110 20 1371:0120 66 1371:0130 64 1371:0140 61 1371:0150 71 1371:0160 D8 1371:0170 75 World !" 65 63 6C 65 62 72 02 02 6C 75 75 20 63 73 3A 88 6C 72 65 61 64 74 06 04 6F 73 6E 20 65 75 94 89 20 20 74 67 66 76 D2 36 57 6F 65 69 67 77 75 6B 6F-72 20-73 7A-65 6E-64 68-69 78-79 C9-4E D7-89 6C 61 20 69 6A 7A 32 0E 64 2D 6D 2E 6B 7B C0 69 20 6D 6F 5C 6C 7C 86 D7 21 69 64 5D 6D 7D 04 C3 65 20 75 5E 6E 7E 46 BE 73 69 6C 5F 6F 0E 3C 48 74 6E 20 60 70 A7 0D DB Hello World !est curs o sa-mi in fluenteze modul de a gindi.\]^_` abcdefghijklmnop qrstuvwxyz{|}~.. ..:...u.N2...F<. u....6k...i...H.

Microprocesoare i Microcontrolere

17

Modificm coninutul registrului CX, astfel nct s conin exact numrul de octei care au fost introdui n memorie ncepnd cu adresa offset 100h i apoi, cu ajutorul conenzii w salvm aceti octei n fiierul HELLO.TXT.
-rcx CX 005E :000D -w Writing 0000D bytes -q

Cu ajutorul editorului NOTEPAD deschidem fiierul HELLO.TXT din folderul Mm.

18

Utilitarul DEBUG. Familia de Microprocesoare 80X86

Microprocesoare i Microcontrolere

19

2. Programe Simple n Limbaj de Asamblare

Dac atam fiecrei instruciuni un mnemonic (anexa A, pentru microprocesoarele 80X86), obinem o reprezentare simbolic a instruciunilor unui microprocesor numit limbaj de asamblare. Translatarea programului scris n limbaj de asamblare n program cod-main se face cu un program special numit asamblor. Productivitatea scrierii programelor n limbajele de nivel nalt (C++, de exemplu) a detronat n timp limbajul de asamblare, cu excepia programrii mixte (asm { }) n care performanele impuse de o anumit aplicaie nu pot fi atinse altfel (situaii frecvent ntlnite att n domenile experimentale ct i n domenii legate de simularea unor procese, fenomene cu ajutorul calculatorului). Deoarece fiecare mnemonic din programul scris (cod ASCII) n limbaj de asamblare este translatat ntr-o singur instruciune n program cod-main, avem o imagine clar a ceea ce execut microprocesorul n fiecare etap a programului. Acesta este marele merit al limbajului de asamblare. Utilitarul DEBUG are integrat un asamblor interactiv cu ajutorul cruia vom ilustra cteva aspecte de baz ale programrii n limbaj de asamblare. Lansm n execuie utilitarul DEBUG i tastm comanda,
-a 1371:0100

dup care asamblorul ateapt introducerea mnemonicelor.


1371:0100 1371:0103 1371:0105 1371:0107 1371:0109 mov mov mov mov ax,CAFE bx,ax cx,bx dx,cx

La prompterul utilitarului DEBUG se ajunge printr-un ([CR],Enter) suplimentar. Dac asamblorul ne semnaleaz o eroare reintroducem toat linia, deoarece adresa offset nu se modific (s nu ne enervm se poate scrie un ntreg capitol despre greelile tipice din aceast etap). Translatarea din programul cod-main n limbajul de asamblare se poate face cu un program desasamblor. Acesta este de asemenea integrat n utilitarul DEBUG. Pentru a vedea rezultatul procesului anterior de asamblare tastm urmtoarea comand:
-u100

20
1371:0100 1371:0103 1371:0105 1371:0107 1371:0109 1371:010A 1371:010D 1371:0111 1371:0116 1371:011B 1371:011D B8FECA 89C3 89D9 89CA C3 A169D7 8B366BD7 C606A7D800 C606A3D800 8B34 006013 MOV MOV MOV MOV RET MOV MOV MOV MOV MOV ADD

Programe Simple n Limbaj de Asamblare


AX,CAFE BX,AX CX,BX DX,CX AX,[D769] SI,[D76B] BYTE PTR [D8A7],00 BYTE PTR [D8A3],00 SI,[SI] [BX+SI+13],AH

Pentru adresele cu offset-ul mai mare sau egal cu 109h pe ecranul unui alt calculator vor fi desigur alte informaii (memoria este tears prin nscriere). Prin comanda precedent putem vedea att modul de translatare a mnemonicelor ct i opcod-urile generate. Pentru a nelege acest mecanism i implicaiile lui tastm urmtoarea comand.
-u101 1371:0101 1371:0103 1371:0105 1371:0107 1371:0109 1371:010A 1371:010D 1371:0111 1371:0116 1371:011B 1371:011D 1371:0120 FECA 89C3 89D9 89CA C3 A169D7 8B366BD7 C606A7D800 C606A3D800 8B34 006013 0E DEC MOV MOV MOV RET MOV MOV MOV MOV MOV ADD PUSH DL BX,AX CX,BX DX,CX AX,[D769] SI,[D76B] BYTE PTR [D8A7],00 BYTE PTR [D8A3],00 SI,[SI] [BX+SI+13],AH CS

Secvena de mnemonice a fost asamblat ncepnd cu adresa offset 100h. Desasamblm ncepnd cu adresa 101h i constatm c microprocesorul ar executa o alt instruciune fr a semnala vreo eroare (probabil aa ceva se ntmpl atunci cnd din senin sistemul se blocheaz). Multe comentarii nu putem face n aceast etap "a hoinrelii noastre prin oraul de numere", aa c tastm n continuare "cuprini de disperarea unei posibile rtciri" urmtoarele comenzi:
-r AX=0000 BX=0000 DS=1371 ES=1371 1371:0100 B8FECA -t AX=CAFE DS=1371 BX=0000 ES=1371 CX=0000 DX=0000 SP=FFEE SS=1371 CS=1371 IP=0100 MOV AX,CAFE BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 SS=1371

DX=0000 CS=1371

SP=FFEE IP=0103

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Microprocesoare i Microcontrolere
1371:0103 89C3 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0105 89D9 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0107 89CA -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0109 C3 MOV BX,AX

21

CX=0000 DX=0000 SP=FFEE SS=1371 CS=1371 IP=0105 MOV CX,BX

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=CAFE DX=0000 SP=FFEE SS=1371 CS=1371 IP=0107 MOV DX,CX

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=CAFE DX=CAFE SS=1371 CS=1371 RET

SP=FFEE IP=0109

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Comanda r ne asigur c regitrii i flag-urile sunt neschimbate, iar cu ajutorul comenzii t rulm programul pas cu pas. Executarea instruciunii de la adresa offset 100h a avut ca efect mutarea (move) numrului CAFEh n registrul AX, iar registrul IP a fost incrementat i conine adresa offset 103h a instruciunii urmtoare. n cod-main mnemonica MOV AX,CAFE a fost translatat sub forma B8FECA. Este uor de neles c opcod-ul B8 este asociat cu MOV AX, iar FECA este numrul pe care dorim s l mutm n registrul AX, scris cu octei inversati. Adic, octetul mai puin semnificativ este la cea mai mic adres (little-endian systems). Aceast convenie este o particularitate a microprocesoarelor Intel ce poate fi semnalat n acest moment. Alte microprocesoare din familia Motorola 68000, de exemplu, utilizeaz convenia opus, octetul cel mai semnificativ la cea mai mic adres (big-endian systems). Putem urmri n continuare opcod-ul (pe doi octei, adic un cuvnt n cazul unor microprocesoare de 16 bii) celorlalte mnemonice i efectele generate de executarea lor. Modul de stabilire a opcod-urilor este o problem prea complicat pentru un viitor novice. O regul specific mnemonicelor microprocesoarelor Intel este dat de modul de exprimare, de la dreapta la stnga, a aciunii dintr-o mnemonic (numrul CAFEh trece n registrul AX, sau coninutul registrului AX trece n registrul BX). Tastm q i prsim utilitarul DEBUG. Acest lucru este necesar pentru a evita o catastrof, blocarea sistemului. Prin rularea pas cu pas a secvenei anterioare de instruciuni, unele informaii importante pentru programul DEBUG au fost distruse. Utilitarul DEBUG ne creaz impresia c microprocesorul este numai la dizpoziia noastr. Este desigur numai o impresie. Dac totui blocm sistemul, putem merge pn la apsarea pe butonul RESET. Dac nu am reuit s blocm

22

Programe Simple n Limbaj de Asamblare

sistemul, vom lansa utilitarul DEBUG pentru o nou aventur. Tastm n continuare comanda
-a 100

i urmtoarele mnemonice:
1371:0100 1371:0103 1371:0105 1371:0107 1371:0109 1371:010A 1371:010B 1371:010C 1371:010D 1371:0110 1371:0112 1371:0114 1371:0116 1371:0117 1371:0118 1371:0119 1371:011A mov ax,CAFE mov bx,ax mov cx,ax mov dx,ax push ax push bx push cx push dx mov dx,BADA mov cx,dx mov bx,cx mov ax,bx pop dx pop cx pop bx pop ax

dup care, pentru a vedea ce se ntmpl, vom rula pas cu pas secvena de instruciuni care a fost asamblat ncepnd cu adresa offset 100h.
-r AX=0000 BX=0000 DS=1371 ES=1371 1371:0100 B8FECA -t AX=CAFE BX=0000 DS=1371 ES=1371 1371:0103 89C3 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0105 89C1 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0107 89C2 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0109 50 -t AX=CAFE BX=CAFE CX=0000 DX=0000 SP=FFEE SS=1371 CS=1371 IP=0100 MOV AX,CAFE CX=0000 DX=0000 SP=FFEE SS=1371 CS=1371 IP=0103 MOV BX,AX CX=0000 DX=0000 SP=FFEE SS=1371 CS=1371 IP=0105 MOV CX,AX CX=CAFE DX=0000 SP=FFEE SS=1371 CS=1371 IP=0107 MOV DX,AX CX=CAFE DX=CAFE SS=1371 CS=1371 PUSH AX CX=CAFE DX=CAFE SP=FFEE IP=0109 BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

SP=FFEC

BP=0000

SI=0000

DI=0000

Microprocesoare i Microcontrolere
DS=1371 ES=1371 1371:010A 53 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:010B 51 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:010C 52 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:010D BADABA -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0110 89D1 -t AX=CAFE BX=CAFE DS=1371 ES=1371 1371:0112 89CB -t AX=CAFE BX=BADA DS=1371 ES=1371 1371:0114 89D8 -t AX=BADA BX=BADA DS=1371 ES=1371 1371:0116 5A -t AX=BADA BX=BADA DS=1371 ES=1371 1371:0117 59 -t AX=BADA BX=BADA DS=1371 ES=1371 1371:0118 5B -t AX=BADA BX=CAFE DS=1371 ES=1371 1371:0119 58 -t SS=1371 CS=1371 PUSH BX CX=CAFE DX=CAFE SS=1371 CS=1371 PUSH CX CX=CAFE DX=CAFE SS=1371 CS=1371 PUSH DX IP=010A NV UP EI PL NZ NA PO NC

23

SP=FFEA IP=010B

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

SP=FFE8 IP=010C

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=CAFE DX=CAFE SP=FFE6 SS=1371 CS=1371 IP=010D MOV DX,BADA CX=CAFE DX=BADA SP=FFE6 SS=1371 CS=1371 IP=0110 MOV CX,DX CX=BADA DX=BADA SP=FFE6 SS=1371 CS=1371 IP=0112 MOV BX,CX CX=BADA DX=BADA SP=FFE6 SS=1371 CS=1371 IP=0114 MOV AX,BX CX=BADA DX=BADA SS=1371 CS=1371 POP DX CX=BADA DX=CAFE SS=1371 CS=1371 POP CX CX=CAFE DX=CAFE SS=1371 CS=1371 POP BX CX=CAFE DX=CAFE SS=1371 CS=1371 POP AX SP=FFE6 IP=0116

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

SP=FFE8 IP=0117

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

SP=FFEA IP=0118

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

SP=FFEC IP=0119

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

AX=CAFE BX=CAFE CX=CAFE DX=CAFE SP=FFEE BP=0000 SI=0000 DI=0000 DS=1371 ES=1371 SS=1371 CS=1371 IP=011A NV UP EI PL NZ NA PO NC 1371:011A 008B3400 ADD [BP+DI+0034],CL SS:0034=18 -

Prin comanda r ne asigurm c regitrii i flag-urile sunt neschimbate. Observm n continuare efectul identic de ncrcare a regitrilor generali prin utilizarea altor instruciuni. Regul: dac nu este o restricie impus de productorul

24

Programe Simple n Limbaj de Asamblare

microprocesorului tot ce pare logic este posibil. De altfel, asamblorul din utilitarul DEBUG tie ce nu se poate. S avem pentru nceput ncredere n semnalizrile lui (Error). La adresa de offset 109h din program avem o instruciune de tip PUSH a crei efect este extrem de important deoarece activeaz un mecanism ntlnit la toate microprocesoarele, stiva. Tot aa cum regitrii CS:IP asigur mpreun rularea programului din segmentul de cod, regitrii SS:SP sunt utilizai mpreun pentru a adresa stiva. Stiva este un segment de memorie (SS) utilizat ca o zon de stocare a informaiei dup regula ultimul intrat primul ieit (last-in first-out, LIFO). Registrul BP este de asemenea asociat cu registrul SS i este utilizat pentru a adresa o anumit locaie de memorie din stiv. Segmentul de stiv poate s se suprapun sau s coincid cu orice alt segment inclusiv cu segmentul de cod (atenie, IP pe timpul rulrii programului pleac de la adrese mici spre adrese mari). Coninutul registrului SP se modific de la adrese mari spre adrese mici (decrementare) cu fiecare octet sau cuvnt copiat pe stiv. Dac programm n limbaj de asamblare trebuie s fim ateni la o eventual coliziune dintre stiv si codul programului (sau dintre stiv si blocul de date), n cazul n care segmentele de memorie se suprapun sau coincid (.COM). nainte de a comenta secvena de instruciuni anterioar s nelegem, de ce este important mecanismul de stiv. Dup cum se poate vedea, numrul regitrilor unui microprocesor este relativ mic (despre microprocesorul de fa se poate spune c are foarte muli regitrii), iar la un moment dat, pentru a continua programul trebuie s sacrificm coninutul unui registru. Dar coninutul lui este important intro etap imediat urmtoare a programului. ntr-o asemenea situaie (dar nu numai) apelm la mecanismul de stiv. Pe de alt parte opcod-ul instruciunilor de tip PUSH este de numai un octet, asigurnd astfel o bun optimizare a programuluicod. Executarea instruciuni PUSH AX a determinat copierea n stiv a cuvntului coninut n registrul AX. Efectul vizibil prin informaia afiat de utilitarul DEBUG ne arat o decrementare cu doi (au fost copiai doi octei) a numrului coninut n registrului SP. Cuvntul din registrul SP point-eaz pe prima adres liber din vrful stivei. Adresa din registrul SP este obinut printr-un proces automat de decrementare/incrementare. Acesta este un alt avantaj al mecanismului de stiv n raport cu operaiile de salvare (prin copiere pe stiv) a unor date care sunt intens utilizate de program. Dup copierea coninutului celor patru regitrii generali n stiv le modificm coninutul prin mutarea cuvntului BADAh n fiecare din acetia (am

Microprocesoare i Microcontrolere

25

folosit alte forme pentru MOV, trebuie puin curaj, dac nu e bine ne informeaz asamblorul interactiv din utilitarul DEBUG). La adresa offset 116h ntlnim instruciunea POP. Dac urmrim cum se modific coninutul regitrilor generali prin executarea acestei secvene, nelegem rolul acestei instruciuni: refacerea coninutului iniial al regitrilor generali. Spunem c stiva a fost descrcat deoarece pe msur ce instruciunile POP sunt executate, coninutul lui SP se ncrementeaz cu doi pentru a ajunge n final (dup refacerea tuturor regitrilor generali) la valoarea iniial. Pentru a nu altera coninutul registrilor n raport cu coninutul lor iniial i cunoscnd mecanismul de stiv (LIFO), trebuie ca restaurarea s o facem n ordine invers. Sunt situaii n care algoritmul impune un alt mod de restaurare a coninutului regitrilor prin mecanismul de stiv (totul este posibil n msura n care este util scopului final, rezolvarea problemei). O alt regul este ca, la ieirea dintr-un program (sau o subrutin), coninutul stivei s fie acelai cu cel din momentul apelrii. Dac problema o cere i aceast regul se poate nclca; acesta este oraul de numere (faci ce vrei, dar ti ce faci ?). Din exemplele anterioare constatm o mixare ciudat de exactitate (vezi efectele desasamblrii ncepnd cu adresa offset 101h) i libertate. Aceasta din urm este dus uneori pn la estravagan, adic un fel de "libertate n lanuri" (Nu cred ca acest curs o sa-mi influenteze modul de a gindi.). Tastai comanda q urmat de exit, i s ne pregtim sufletete pentru ntlnirea cu vectorii de ntrerupere. Vectorii de ntrerupere sunt marea "gselni" prezent n orice calculator modern. Acetia au o zon de memorie rezervat, numit tabela vectorilor de ntrerupere. Dac din utilitarul DEBUG tastm comanda
-d0:0 0000:0000 0000:0010 0000:0020 0000:0030 0000:0040 0000:0050 0000:0060 0000:0070 -d 0000:0080 0000:0090 0000:00A0 0000:00B0 0000:00C0 0000:00D0 0000:00E0 0000:00F0 9E 65 00 6F 07 39 A4 1D A8 17 6C 6C EA 6C 6C 6C 0F 04 00 EF 00 E7 E7 00 0F 03 10 10 E4 10 10 10 C9 70 00 00 70 00 00 00 C9 F6 C9 C9 0F C9 C9 C9 00 00 C8 F0 C8 F0 F0 C8 00 0C 00 00 C9 00 00 00 65 54 28 6F 4D 40 2F A4 2F BC 66 6C 00 6C 6C 6C 04 FF 00 EF F8 02 00 F0 04 0F 04 10 EF 10 10 10 70 00 87 00 00 0B 48 00 5F C9 70 C9 00 C9 C9 C9 00-16 F0-88 08-6F F0-9A F0-41 02-2D 09-6E F0-22 09-4F 00-C6 00-B4 00-62 F0-6C 00-6C 00-6C 00-6C 00 80 EF 00 F8 04 FE 05 03 0F 05 01 10 10 10 10 87 00 00 87 00 70 00 00 F6 C9 51 13 C9 C9 C9 C9 08 F0 F0 08 F0 00 F0 00 0C 00 02 0B 00 00 00 00 65 6F 6F 65 7F 28 04 93 8A D0 6C CC 01 6C 6C 6C 04 EF EF 04 25 0A 06 49 03 0F 10 01 00 10 10 10 70 00 00 70 A7 51 51 00 F6 C9 C9 14 3F C9 C9 C9 00 F0 F0 00 FD 02 02 C0 0C 00 00 0B 0A 00 00 00 ....e.p.....e.p. e.p.T.......o... ....(...o...o... o...o.......e.p. ..p.M...A....%.. 9...@...-.p.(.Q. ..../.H.n.....Q. ........"....I.. ..../._.O....... ................ l...f.p...Q.l... l...l...b....... ........l.....?. l...l...l...l... l...l...l...l... l...l...l...l...

26

Programe Simple n Limbaj de Asamblare

putem vedea o parte din coninutul acestei zone (adresa maxim a zonei este 3FFh, 1 Kbyte). Fiecare va vedea altceva, tocmai de aceea calculatoarele noastre sunt compatibile ntre ele. Iniial, ntreruperile au fost introduse pentru a putea cere atenia unitii centrale n clipa cnd anumite evenimente imprevizibile au loc (ntreruperi hard, le lsam pe mai trziu). Pe lng ntreruperile hard microprocesoarele 80X86 mai au nc dou tipuri de ntreruperi: ntreruperi excepionale (apariia unor situaii cu totul deosebite, mprire cu zero, ) i ntreruperile soft (INT). Asamblm urmtoarea secven de instruciuni:
-a 1371:0100 1371:0103 1371:0105 1371:0107 1371:0109 1371:010C 1371:010E 1371:010F mov mov mov mov mov int nop cx,0 dh,18 dl,4f bh,70 ax,600 10

i o rulm pas cu pas s vedem ce se ntmpl.


-r AX=0000 BX=0000 DS=1371 ES=1371 1371:0100 B90000 -t AX=0000 BX=0000 DS=1371 ES=1371 1371:0103 B618 -t AX=0000 BX=0000 DS=1371 ES=1371 1371:0105 B24F -t AX=0000 BX=0000 DS=1371 ES=1371 1371:0107 B770 -t AX=0000 BX=7000 DS=1371 ES=1371 1371:0109 B80006 -t CX=0000 DX=0000 SP=FFEE SS=1371 CS=1371 IP=0100 MOV CX,0000 BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 DX=0000 SP=FFEE SS=1371 CS=1371 IP=0103 MOV DH,18

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 DX=1800 SP=FFEE SS=1371 CS=1371 IP=0105 MOV DL,4F

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 DX=184F SP=FFEE SS=1371 CS=1371 IP=0107 MOV BH,70

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 DX=184F SP=FFEE SS=1371 CS=1371 IP=0109 MOV AX,0600

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Microprocesoare i Microcontrolere

27

AX=0600 BX=7000 DS=1371 ES=1371 1371:010C CD10 -t AX=0600 BX=7000 DS=1371 ES=1371 C870:0007 FB -t AX=0600 BX=7000 DS=1371 ES=1371 C870:0008 84E4 -

CX=0000 DX=184F SS=1371 CS=1371 INT 10

SP=FFEE IP=010C

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 DX=184F SS=1371 CS=C870 STI

SP=FFE8 IP=0007

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC

CX=0000 DX=184F SP=FFE8 SS=1371 CS=C870 IP=0008 TEST AH,AH

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Pn la adresa offset 10Ch nimic nou, aici urmeaz s fie executat instruciunea INT 10, care are opcod-ul CD urmat de 10, numrul invocat de INT. Execuia acestei instruciuni are efecte neateptate. Observm c s-a modificat coninutul regitrilor CS:IP, dovad c suntem n alt segment de memorie i la o alt adres offset. De asemenea, a fost decrementat registrul SP, care de fapt ne informeaz c au fost copiai pe stiv ase octei. De asemenea flag-ul interrupt, EI (ntreruperile erau activate) a trecut n DI (ntreruperile sunt dezactivate), pentru ca mai apoi s fie repus n starea EI de ctre instruciunea STI (opcod, FB). De ce aceast instruciune a determinat aceste schimbri profunde i de unde a fost luat noul coninut al regitrilor CS:IP? S privim n tabela vectorilor de ntrerupere n dreptul adresei offset 40h (0000:0040 07 00 70 C8). Dac ne aducem aminte de convenia specific microprocesoarelor Intel (little-endian systems), atunci rspunsul cu privire la noul coninut al regitrilor CS:IP este urmtorul: noul coninut al regitrilor CS:IP a fost copiat din tabela vectorilor de ntrerupere. Mai mult, n regitrii CS:IP au fost copiai patru octei (4*10h = 40h), de unde putem deduce regula dup care este organizat tabela vectorilor de ntrerupere. Aa c, numrul de dup o instruciune de tip INT este de fapt numrul unei intrri din tabela vectorilor de ntrerupere. Pentru microprocesoarele din familia 80X86 avem 256 de ntreruperi posibile (INT 0, INT 1, , INT FF). De asemenea, nu putem s nu remarcm ct de puternic este acest mecanism prin care invocm sistemului de operare un serviciu. Pentru aceasta este suficient s invocm ntreruperea aferent serviciului respectiv, indiferent unde este localizat (n memoria fizic) programul care deseverte acest serviciu. O comparaie cu telefonia celular nu este lipsit de temei. Noi apelm un numr de telefon, iar abonatul poate fi oriunde. Mai mult, abonatul ne poate informa c este n alt loc dect cel real. n acest caz, abonatul este un posibil virus.

28

Programe Simple n Limbaj de Asamblare

Mai trebuie s nelegem cteva amnunte deloc lipsite de importan. Executarea instruciunii de ntrerupere a dezactivat automat ntreruperile. Aa c, nu vom fi deranjai de o eventual alt ntrerupere. n cazul serviciului invocat programatorul nu a dorit acest lucru i ntreruperile au fost reactivate prin instruciunea STI. Probabil c ntreruperea invocat nu execut ceva foarte important. O alt problem ce trebuie lmurit este legat de copierea pe stiv a celor ase octei. Este uor de bnuit c patru dintre aceti octei sunt de fapt vechiul coninut al regitrilor CS:IP. Dup ce serviciul invocat va fi executat, cu siguran trebuie s revenim la programul iniial (deci IP va pointa pe instruciunea urmtoare lui INT, nainte de a fi copiat pe stiv) pentru a continua cu instruciunea urmtoare. Ce altceva ar mai putea fi, cu siguran, distrus de serviciul invocat ? Flagurile. Tocmai de aceea, flag-urile sunt copiate automat n stiv (flag-urile formeaz un registru de 16 bii, utilitarul DEBUG ne afieaz doar starea a opt flag-uri) la executarea unei instruciuni INT. Tastm comanda q i relansm utilitarul DEBUG. Asamblm aceeai secven de instruciuni i tastm comanda g10E. Aceasta va asigura execuia tuturor instruciunilor pn la adresa 10Eh .
-a 1371:0100 1371:0103 1371:0105 1371:0107 1371:0109 1371:010C 1371:010E 1371:010F -g10e mov mov mov mov mov int nop cx,0 dh,18 dl,4f bh,70 ax,600 10

AX=0600 BX=7000 DS=1371 ES=1371 1371:010E 90 -

CX=0000 DX=184F SS=1371 CS=1371 NOP

SP=FFEE IP=010E

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Presupunerile fcute asupra modului de aciune al intruciuni INT s-au adeverit. Registrul SP a fost incrementat pn la valoarea avut iniial. Ceilali regitri au, de asemenea, coninutul neschimbat n raport cu situaia precedent invocrii ntreruperii. Flag-urile sunt, de asemenea, neschimbate n raport cu situaia iniial. Am spune c nu s-a ntmplat nimic. Numai c modul de lucru al ecranului a fost revers-at i tot ce era afiat a fost ters. Aceast secven de instruciuni face ceva, aa c, este n sfrit un program. Acesta terge tot ce este afiat pe ecran i face revers. Tastm comanda q urmat de exit. Cu ajutorul utilitarului DEBUG rescriem programul. Se putea i altfel, dar s nu ne grbim.

Microprocesoare i Microcontrolere

29

-a 1371:0100 mov 1371:0103 mov 1371:0105 mov 1371:0107 mov 1371:0109 mov 1371:010C int 1371:010E mov 1371:0111 int 1371:0113 -rcx CX 0000 :13 -nclrscr.com -w Writing 00013 -q

cx,0 dh,18 dl,4f bh,70 ax,600 10 ax,4c00 21

bytes

Cu ajutorul comenzii DIR putem constata existena primului nostru program scris n limbaj de asamblare. Acum l putem apela simplu de la linia de comand
C:\Mm>clrscr

urmat evident de
C:\Mm>exit

pentru a reface starea iniial a ecranului. Cteva precizri sunt necesare nainte de o nou "hoinreal". Invocarea diverselor servicii ale sistemului de operare prin mecanismul ntreruperilor simplific mult lucrurile. Nu trebuie s tim dect numrul ntreruperii. Acesta este folosit de microprocesor pentru aflarea adresei fizice din tabela vectorilor de ntrerupere. Adresa se poate schimba de la un fabricant la altul sau de la o versiune la alta a sistemului de operare. Pentru a asigura compatibilitatea nu trebuie dect respectat cu strictee ordinea vectorilor n tabel. Acest mecanism asigur portabilitatea programelor ntre toate calculatoarele IBM PC (o veste bun pentru viitorii hacker-i, orice vector din aceasta tabel poate fi schimbat cu uurin). Momentan trebuie s reinem c sistemul de operare al calculatoarelor IBM PC nglobeaz componenta BIOS (aceast component rspunde n principal de gestionarea echipamentelor de intrare/ieire). Aceasta este o colecie de servicii coninute ntr-o memorie nevolatil de pe placa de baz a calculatorului. Deci n BIOS vom gsi gata scrise i puse la punct, o serie ntreag de subrutine legate de echipamentele de intrare/ieire. Ce bine c le putem folosi, fr a ne mai bate capul

30

Programe Simple n Limbaj de Asamblare

cu scrierea lor de fiecare dat, cnd dezvoltm o aplicaie. Apelarea acestor subrutine se face, bineneles, prin ntreruperi. Pentru lucrul cu fiecare echipament periferic a fost alocat o ntrerupere soft. Aceste ntreruperi nu trebuie ncurcate cu ntreruperile hard, care lucreaz cu echipamentele de intrare/ieire, ntr-un mod pe care momentan l considerm transparent pentru noi. Principalele ntreruperi BIOS sunt rezumate mai jos:
INT INT INT INT INT INT INT INT INT 10h 13h 14h 16h 17h 5h 19h 1Ah 20h ; ; ; ; ; ; ; Servicii de ecran Servicii de disc Servicii de comunicaii seriale Servicii de tastatur Servicii de imprimant Copiere ecran la imprimant Activare bootstrap (rencrcare sistem de operare, de regul MS-DOS) ; Servicii de timp i data. ; Terminare program

In cadrul fiecrei ntreruperi se pot face mai multe "chestii", acestea sunt serviciile. Selecia serviciului dorit se face prin ncrcarea, nainte de invocarea ntreruperii, a registrului AH, cu numrul serviciului. Parametrii de apel ai serviciului se ncarc la fel, n anumii regitrii, dup caz. Atenie mare, unele servicii distrug coninutul unor regitrii. Dac avem n regitrii ce urmeaz s fie distrui date utile, coninutul acestora trebuie copiat pe stiv, nainte de apelarea ntreruperii. Vom numi servicii DOS (servicii ale sistemului de operare), ntregul set de operaii pe care sistemul de operare le pune la dispoziie. Aceste servicii se mpart n ntreruperi DOS i funcii DOS. ntreruperile DOS sunt invocate prin instruciunea INT cu tipul rezervat pentru fiecare ntrerupere n parte. Pe de alt parte funciile DOS, cam la fel ca serviciile BIOS, sunt invocate printr-o singur ntrerupere, numit ntrerupere umbrel. Aceasta este INT 21 (4*21h = 84h, 0000:0080 A8 0F C9 00 2F 04 5F 09-4F 03 F6 0C 8A 03 F6 0C) iar parametrul din registrul AH fixeaz serviciul solicitat. ntreruperile i funciile DOS vor fi studiate individual. Exist mult documentaie i programe tutoriale legate de modul de invocare al acestora, respectiv serviciile oferite (funcie de coninutul regitrilor n momentul invocrii). O parte din serviciile oferite de componenta BIOS sunt dublate de componenta DOS. De regul, este preferat invocarea variantei DOS a seviciului cu scopul asigurrii unei portabiliti mai bune a programului. Programatorul este un om i ca orice om uit. Tocmai de aceea, este bine s comentm programul pe msur ce l scriem. Obinem odat cu programul i documentaia acestuia. Partea de comentariu care va nsoi fiecare instruciune nu trebuie introdus n cazul asamblorului interactiv din utilitarul DEBUG. Dar dac utilizm un editor i un asamblor extern (MASM sau TASM, de exemplu) este bine

Microprocesoare i Microcontrolere

31

s o facem. La fel n cadrul programrii mixte, la scrierea unor funcii n limbaj de asamblare, este indicat ca fiecare instruciune s fie urmat de un comentariu (asm { }, acest stil de programare este de altfel scopul acestei cri). Pentru a nelege modul de utilizare concret a serviciilor BIOS i DOS, asamblm i salvm urmtorul program.
-a 1371:0100 1371:0103 1371:0106 1371:0108 1371:010B 1371:010D mov mov mov mov int mov cx,0 dx,184f bh,70 ax,600 10 dx,119 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; linia / coloana colul stnga sus linia / coloana colul dreapta jos atributul liniilor blank fixm serviciul, scroll page up invocare ntrerupere BIOS adresa offset a primului caracter al irului de tiprit fixm serviciul, tiprete ir de caractere pn la caracterul $ (end of string, EOS) invocare ntrerupere DOS fixm serviciul, exit invocare ntrerupere DOS db, pseudo-instruciune, irul de tiprit caractere de control, LF (line feed), CR (carriage return), , EOS

1371:0110 mov ah,09

1371:0112 1371:0114 1371:0117 1371:0119

int 21 mov ax,4c00 int 21 db "Hello World !"

1371:0126 db 0a,0d,0a,0d,"$" 1371:012B -rcx CX 0000 :2b -nhello.com -w Writing 0002B bytes

Tastm n continuare urmtoarea comand:


-g112

AX=0900 BX=7000 DS=1371 ES=1371 1371:0112 CD21 -t

CX=0000 DX=0119 SS=1371 CS=1371 INT 21

SP=FFEE IP=0112

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

AX=0900 BX=7000 CX=0000 DX=0119 SP=FFE8 DS=1371 ES=1371 SS=1371 CS=095F IP=042F 095F:042F EAA0045102 JMP 0251:04A0 -

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC

i analizm coninutul regitrilor CS:IP i SP. Constatm respectarea tuturor anticipaiilor fcute pentru serviciile DOS legate de INT 21h i de aceast dat flagul interrupt s-a modificat (adic, ntreruperile au fost dezactivate).

32

Programe Simple n Limbaj de Asamblare

De fiecare dat asamblarea s-a fcut automat ncepnd cu adresa offset 100h. Pentru a vedea ce este pn la aceast adres tastm comanda q urmat de exit i apoi lansm utilitarul DEBUG. Tastm n continuare urmtoarele comenzi:
-nhello.com -l -d0 1393:0000 CD 1393:0010 F6 1393:0020 FF 1393:0030 F6 1393:0040 07 1393:0050 CD 1393:0060 4C 1393:0070 20 -d 1393:0080 09 1393:0090 00 1393:00A0 00 1393:00B0 00 1393:00C0 00 1393:00D0 00 1393:00E0 00 1393:00F0 00 -d 1393:0100 B9 1393:0110 B4 1393:0120 6F 1393:0130 53 1393:0140 3A 1393:0150 59 1393:0160 87 1393:0170 2A -

20 0C FF 0C 0A 21 4F 20 48 00 00 00 00 00 00 00 00 09 72 8B 74 E2 65 00

00 17 FF 14 00 CB 20 20 45 00 00 00 00 00 00 00 00 CD 6C 1E 0B 65 E3 83

A0 03 FF 00 00 00 20 20 4C 00 00 00 00 00 00 00 BA 21 64 5F C6 E3 2A 06

00 F6 FF 18 00 00 20 20 4C 00 00 00 00 00 00 00 4F B8 20 E2 87 01 2E 5F

9A 0C FF 00 00 00 43 20 4F 00 00 00 00 00 00 00 18 00 21 80 65 1E 43 E2

F0 E5 FF 93 00 00 4F 20 2E 00 00 00 00 00 00 00 B7 4C 0A BF E3 59 43 01

FE-1D 0C-01 FF-FF 13-FF 00-00 00-00 4D-00 20-00 43-4F 00-00 00-00 00-00 00-00 00-00 00-00 00-00 70-B8 CD-21 0D-0A 64-E3 5C-43 E2-80 83-06 5B-C3

F0 01 FF FF 00 00 00 00 4D 00 00 00 00 00 00 00 00 48 0D 5C 83 3E 5F 57

4F 01 FF FF 00 00 00 00 0D 00 00 00 00 00 00 00 06 65 24 74 06 5D E2 8B

03 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 CD 6C 01 12 5F E2 02 3E

F6 02 82 00 00 00 00 00 00 00 00 00 00 00 00 00 10 6C 06 80 E2 00 C7 5B

0C FF 13 00 00 48 20 00 00 00 00 00 00 00 00 00 BA 6F 5B BF 01 75 87 E2

8A FF 5E 00 00 45 20 00 00 00 00 00 00 00 00 00 19 20 E2 64 C7 0D 65 AC

03 FF 3E 00 00 4C 20 00 00 00 00 00 00 00 00 00 01 57 C3 E3 06 C7 E3 AA

. ........O..... ................ ..............^> ................ ................ .!...........HEL LO COM..... ........ .HELLO.COM...... ................ ................ ................ ................ ................ ................ ................ ....O..p........ ...!..L.!Hello W orld !....$..[.. S.._...d.\t...d. :t...e.\C.._.... Y.e...Y..>]..u.. .e.*.CC.._....e. *..._..[.W.>[...

i putem admira coninutul memoriei n zona de adrese offset 0h - 17Fh. Blocul de memorie cuprins ntre adresele offset 00h i FFh se numete PSP (Program Status Prefix). Acest bloc este construit de sistemul de operare la ncrcarea programului i conine informaii vitale despre programul ce urmeaz a fi rulat. Totodat, acest bloc ofer puntea de legtur ntre program i resursele soft oferite de sistemul de operare. Linia de comand (de la prompterul DOS) care lanseaz programul n execuie este mprit n nume, parametrii i opiuni. Tot ce urmeaz numelui, pn la terminator ([CR]), va fi copiat i n PSP ncepnd cu poziia 81h, n forma ASCII. Lungimea acestor informaii este ncrcat n octetul de pe poziia 80h. De aici programul va copia aceste informaii i le va folosi n cadrul task-urilor programului. ncepnd cu adresa offset 100h putem vedea forma cod-main a programului. Pentru a vedea legtura dintre

Microprocesoare i Microcontrolere

33

program i sistemul de operare fcut prin PSP, modificm programul astfel (este i un prim exerciiu de reverse-engineering, nu vom plti daune nici unei firme deoarece programul HELLO.COM este produsul nostru):
-u100 1393:0100 1393:0103 1393:0106 1393:0108 1393:010B 1393:010D 1393:0110 1393:0112 1393:0114 1393:0117 1393:0119 1393:011A 1393:011B 1393:011C 1393:011D 1393:011E B90000 BA4F18 B770 B80006 CD10 BA1901 B409 CD21 B8004C CD21 48 65 6C 6C 6F 20576F MOV MOV MOV MOV INT MOV MOV INT MOV INT DEC DB DB DB DB AND CX,0000 DX,184F BH,70 AX,0600 10 DX,0119 AH,09 21 AX,4C00 21 AX 65 6C 6C 6F [BX+6F],DL

Pentru nceput s ne convingem c programul nu a suferit modificri. ncepnd cu adresa 119h este irul ce urmeaz s fie tiprit pe ecranul calculatorului. Dar acest lucru nu-l tie desasamblorul i cu att mai puin microprocesorul. Aceste maini stupide sunt gata s interpreteze i s execute orice numr gsit n segmentul de cod. Aa c, pentru ele orice numr este un posibil opcode sau pseudo-instruciune. ncepnd cu adresa offset 114h a programului ne pregtim de ieire (cu pace s ieim ) i realizm efectiv acest lucru prin invocarea unui serviciu DOS. Modificm aceast zon a programului astfel:
-a114 1393:0114 1393:0115 -u100 1393:0100 1393:0103 1393:0106 1393:0108 1393:010B 1393:010D 1393:0110 1393:0112 1393:0114 1393:0115 1393:0118 1393:011B 1393:011C 1393:011D ret

B90000 BA4F18 B770 B80006 CD10 BA1901 B409 CD21 C3 004CCD 214865 6C 6C 6F

MOV MOV MOV MOV INT MOV MOV INT RET ADD AND DB DB DB

CX,0000 DX,184F BH,70 AX,0600 10 DX,0119 AH,09 21 [SI-33],CL [BX+SI+65],CX 6C 6C 6F

34
1393:011E 20576F AND

Programe Simple n Limbaj de Asamblare


[BX+6F],DL

i observm modul n care a fost translatat aceast nou instruciune (RET, RETurn). Opcod-ul su este numai de un octet aa c zona de patru octei cuprins ntre adresele de offset 115h i 118h va rmne practic izolat. Este uor de bnuit c se va ntoarce undeva, pentru a afla unde tastm comanda
-g114

Hello World !

AX=0924 BX=7000 DS=1393 ES=1393 1393:0114 C3 -t AX=0924 BX=7000 DS=1393 ES=1393 1393:0000 CD20 -t AX=0924 BX=7000 DS=1393 ES=1393 00C9:0FA8 90 -g

CX=0000 DX=0119 SS=1393 CS=1393 RET

SP=FFFE IP=0114

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 DX=0119 SS=1393 CS=1393 INT 20

SP=0000 IP=0000

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0000 DX=0119 SS=1393 CS=00C9 NOP

SP=FFFA IP=0FA8

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC

Program terminated normally -

i ne ndreptm ca de obicei atenia spre regitrii i flag-urile microprocesorului (adic, spre tot ce are). Constatm o surprinztoare modificare a registrului IP astfel nct pointeaz la adresa 0h, adic la nceputul PSP-ului. Aici microprocesorul a descoperit opcod-ul instruciunii INT 20 (terminare program). Cu ajutorul comenzii g trecem peste aceast procedur. Descoperii singuri n tabela vectorilor de ntrerupere, valoarea din regitrii CS:IP, cu scopul de a determina adresa fizic a rutinei ce asigur acest serviciu. n concluzie, putem spune c la nceputul PSP-ului, pe primi doi octei sistemul de operare pune opcod-ul instruciuni INT 20. Este bine s tim c pe urmtorii doi octei este specificat lungimea programului exprimat n multiplii de 16 octei. Dei funcioneaz corect, pentru compatibilitate este preferat versiunea iniial a programului. De altfel, din motive de siguran vom utiliza pe ct este posibil ntreruperile i funciile DOS. Pentru a ncheia ziua de munc, tastm comanda q urmat de exit, apoi de la promterul MS-DOS lansm n execuie programul zilei.

Microprocesoare i Microcontrolere

35

C:\Mm>hello

36

Programe Simple n Limbaj de Asamblare

Microprocesoare i Microcontrolere

37

3. Circuite Specializate Programabile

Un embedded system fr periferice de intrare/ieire este ca o cas fr ui i ferestre. Nu putem s ne lipsim de ui i ferestre pentru c locuina ar deveni inutil. Similar, un embedded system (un calculator IBM PC, n acest caz) nu are sens fr o periferie de intrare/ieire. De altfel, nc de la nceput, odat cu microprocesoarele au fost concepute i unele circuite specializate pentru periferie. Aa c, fiecare firm a realizat o serie de circuite specializate (pentru un domeniu specific de aplicaii) programabile pentru o familie dat de microprocesoare. Deoarece transferul cte unui byte s-a considerat acceptabil pentru perifericele uzuale, familia de microprocesoare 80X86 (de la Intel) a motenit practic nemodificate circuitele specializate programabile ale microprocesorului 8080 (primul microprocesor "adevrat" de 8 bii). Este probabil greu de neles legtura dintre conceptul de circuit specializat i cel de circuit programabil. S ne imaginm un membru al unui partid politic, el este specializat n msura n care promoveaz politica partidului i programabil atunci cnd trebuie s voteze. S ncercm s ne dezmorim puin i s lansm n execuie utilitarul DEBUG. Tastm urmtoarele comenzi i secvene de instruciuni:
-a 1371:0100 mov consol 1371:0102 mov 1371:0104 int 1371:0106 mov 1371:0109 int 1371:010B -nbeep1.com -rcx CX 0000 :b -w Writing 0000B -q ah,02 dl,07 21 ax,4c00 21 ; fixm serviciul, scrie caracter la ; ; ; ; codul ASCII al caracterului BEL invocm ntrerupere DOS fixm serviciul, exit invocm ntrerupere DOS

bytes

De la prompterul MS-DOS lansm n execuie programul realizat (beep1.com). Dac calculatorul pe care lucrm are plac de sunet, s nu uitm s conectm boxele. Dup cum era uor de bnuit, caracterul ASCII 7h numit BEL nu este tiprit, el produce un sunet n difuzor. Noi am auzit efectul rulrii programului beep1.com datorit faptului c exist un periferic specializat n producerea de sunete.

38

Circuite Specializate Programabile

Mai nainte de a vedea dac acest periferic este i programabil s ne mai antrenm puin n scrierea de programe n limbaj de asamblare. Lansm n execuie utilitarul DEBUG i realizm programul beep2.com.
-a 1371:0100 jmp 119 1371:0102 mov ah,02 1371:0104 mov dl,07 1371:0106 int 21 1371:0108 ret 1371:0109 mov bx,01ff 1371:010C mov cx,ffff 1371:010F nop 1371:0110 loopnz 10f 1371:0112 dec bx 1371:0113 cmp bx,0000 1371:0116 jnz 10c 1371:0118 ret 1371:0119 call 102 1371:011C call 109 1371:011F call 102 1371:0122 mov ax,4c00 1371:0125 int 21 1371:0127 -nbeep2.com -rcx CX 0000 :27 -w Writing 00027 bytes -q ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; salt necondiionat la add. offset 119h fixm serviciul, - subrutina - scrie BEL codul ASCII al caracterului BEL invocm ntrerupere DOS return, subrutina scrie BEL subrutina delay, n BX numr repetri loop n CX numr de repetri n loop nu face nimic, consumm timp dac CX > 0, repet de la adresa offset 10Fh decrementm DX este BX = 0h dac este diferit de 0h salt la 10Ch return, subrutina delay aici sare jmp, apelm subrutina - scrie BEL apelm subrutina delay apelm subrutina - scrie BEL fixm seviciul, exit invocm ntrerupere DOS

De la prompterul MS-DOS lansm programul beep2.com n execuie i ascultm cu atenie. Dar dac auzim trebuie s i nelegem instruciunile din precedentul program. Prin subrutin se nelege o secven de instruciuni, scris separat, care poate fi apelat din diferite puncte ale unui program. Subrutinele grupeaz unele secvene de instruciuni care sunt frecvent apelate, eventual cu parametri diferii. Parametrii pot fi transferai prin regitri sau prin stiv. Mecanismul de implementare a subrutinelor este realizat cu ajutorul instruciunilor CALL i RET. Subrutinele se pot gsi n acelai segment cu programul apelant (apelare intrasegment - near) sau n segmente diferite (apelare intersegment far). Pentru cele dou cazuri, avem mnemonice diferite, aa c vor fi generate opcod-uri diferite. Cnd se face un CALL, adresa unde urmeaz s se fac ntoarcerea (adresa urmtoarei instruciuni) este copiat pe stiv. Cnd se face ntoarcerea prin RET, acea adres este scoas din stiv rencrcnd registrul IP.

Microprocesoare i Microcontrolere

39

Mai mult, subrutinele pot fi imbricate, adic o subrutin poate apela o alt subrutin. Folosirea stivei permite acest lucru. Astfel, primul RET va fi pereche cu ultimul CALL. Reinem, apelurile intrasegment salveaz doar offset-ul adresei de revenire. La RET aceast valoare se rencarc n registrul IP. Apelurile intersegment salveaz att coninutul registrului segment CS, ct i offset-ul din registrul IP; la RETF ambele sunt reactualizate. n cazul n care, subrutina altereaz (folosete) regitrii a cror coninut este necesar n programul apelant, aceti regitrii sunt salvai i ei pe stiv, cu PUSH. Dup revenire, valorile lor sunt refcute cu POP, de regul n ordinea invers salvrii. Dac utilizm asamblorul din utilitarul DEBUG este bine s scriem prima dat subrutinele, pentru a ti ulterior care este adresa de offset a acestora. Pentru a trece peste aceast parte a programului folosim o intruciune de salt necondiionat. Implementarea buclelor (ciclurilor) ntr-un program se face cu instruciuni LOOP. Registrul CX este iniializat cu numrul de repetri i la fiecare executare a unei instruciuni LOOP este decrementat cu o unitate. Condiia de ieire din bucl este de regul dat de evaluarea automat a coninutului registrului CX. Subrutinele de ntrziere (delay) sunt eseniale pentru realizarea unor temporizri ntr-o aplicaie dat. De asemenea, ele sunt importante n etapa de punere la punct a unui program care lucreaz cu un periferic. Acest lucru se datoreaz vitezei mari de execuie a intruciunilor. La o rulare normal este posibil s nu putem observa nimic prin intermediul simurilor noastre. Dup cum uor se poate constata., explicaiile devin din ce n ce mai generale (s nu uitm de anexa A). Acest lucru se datoreaz experienei pe care o avem n exploatarea utilitarului DEBUG. Toate aceste programe pot fi rulate pas cu pas (trace) urmrind cu atenie ce se ntmpl. Scopul este s nvm, lucrnd tot timpul la calculator. Un exemplu de utilizare inteligent a comenziilor utilitarului DEBUG va fi prezentat n continuare. Noi tim ce va face programul pe msur ce fiecare instruciune este scris, aa c trebuie doar s ne convingem c microprocesorul ajunge n fiecare etap la starea anticipat de noi.
C:\Mm>debug -nbeep2.com -l -u 1393:0100 EB17 1393:0102 B402 1393:0104 B207 1393:0106 CD21 1393:0108 C3 1393:0109 BBFF01 1393:010C B9FFFF 1393:010F 90

JMP MOV MOV INT RET MOV MOV NOP

0119 AH,02 DL,07 21 BX,01FF CX,FFFF

40

Circuite Specializate Programabile

1393:0110 E0FD LOOPNZ 010F 1393:0112 4B DEC BX 1393:0113 83FB00 CMP BX,+00 1393:0116 75F4 JNZ 010C 1393:0118 C3 RET 1393:0119 E8E6FF CALL 0102 1393:011C E8EAFF CALL 0109 1393:011F E8E0FF CALL 0102 -u 1393:0122 B8004C MOV AX,4C00 1393:0125 CD21 INT 21 1393:0127 010659E2 ADD [E259],AX 1393:012B 01065BE2 ADD [E25B],AX 1393:012F C3 RET 1393:0130 53 PUSH BX 1393:0131 8B1E5FE2 MOV BX,[E25F] 1393:0135 80BF64E35C CMP BYTE PTR [BX+E364],5C 1393:013A 7412 JZ 014E 1393:013C 80BF64E33A CMP BYTE PTR [BX+E364],3A 1393:0141 740B JZ 014E -r AX=0000 BX=0000 CX=0027 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 DS=1393 ES=1393 SS=1393 CS=1393 IP=0100 NV UP EI PL NZ NA PO NC 1393:0100 EB17 JMP 0119 -t AX=0000 BX=0000 DS=1393 ES=1393 1393:0119 E8E6FF -t AX=0000 BX=0000 DS=1393 ES=1393 1393:0102 B402 -t AX=0200 BX=0000 DS=1393 ES=1393 1393:0104 B207 -t AX=0200 BX=0000 DS=1393 ES=1393 1393:0106 CD21 -t=108 AX=0200 BX=0000 DS=1393 ES=1393 1393:011C E8EAFF -t AX=0200 DS=1393 BX=0000 ES=1393 CX=0027 DX=0000 SP=FFFE SS=1393 CS=1393 IP=0119 CALL 0102 BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0027 DX=0000 SP=FFFC SS=1393 CS=1393 IP=0102 MOV AH,02

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0027 DX=0000 SP=FFFC SS=1393 CS=1393 IP=0104 MOV DL,07

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0027 DX=0007 SS=1393 CS=1393 INT 21

SP=FFFC IP=0106

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0027 DX=0007 SP=FFFE SS=1393 CS=1393 IP=011C CALL 0109

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0027 SS=1393

DX=0007 CS=1393

SP=FFFC IP=0109

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Microprocesoare i Microcontrolere
1393:0109 BBFF01 -t AX=0200 BX=01FF DS=1393 ES=1393 1393:010C B9FFFF -t AX=0200 BX=01FF DS=1393 ES=1393 1393:010F 90 -t AX=0200 BX=01FF DS=1393 ES=1393 1393:0110 E0FD -t AX=0200 BX=01FF DS=1393 ES=1393 1393:010F 90 -t AX=0200 BX=01FF DS=1393 ES=1393 1393:0110 E0FD -t=118 AX=0200 BX=01FF DS=1393 ES=1393 1393:011F E8E0FF -t=122 AX=4C00 BX=01FF DS=1393 ES=1393 1393:0125 CD21 -g MOV BX,01FF

41

CX=0027 DX=0007 SP=FFFC SS=1393 CS=1393 IP=010C MOV CX,FFFF

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=FFFF DX=0007 SS=1393 CS=1393 NOP

SP=FFFC IP=010F

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=FFFF DX=0007 SP=FFFC SS=1393 CS=1393 IP=0110 LOOPNZ 010F

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=FFFE DX=0007 SS=1393 CS=1393 NOP

SP=FFFC IP=010F

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=FFFE DX=0007 SP=FFFC SS=1393 CS=1393 IP=0110 LOOPNZ 010F

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=FFFE DX=0007 SP=FFFE SS=1393 CS=1393 IP=011F CALL 0102

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=FFFE DX=0007 SS=1393 CS=1393 INT 21

SP=FFFE IP=0125

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Program terminated normally -

Dac pe aceste programe facem experiene, trebuie s lucrm cu atenie. Numai astfel, nu vom bloca calculatorul (oricum nu se va strica fizic). Sfat: numai i numai dac nu reuim prin CTRL-ALT-DEL urmat de [End-Task] vom apsa butonul RESET. De exemplu, funcie de calculatorul pe care lucrm va trebui s fixm parametrul din registrul BX. Prin acest parametru stabilim numrul de repetri pentru bucla pricipal (de la adresa offset 109h) a subrutinei de ntrziere din programul precedent. Aceast valoare depinde de performanele reale ale calculatorului (frecvena de tact, clock, ceas) pe care lucrm. Dac nu ne convine

42

Circuite Specializate Programabile

parametrul actual nu vom rescrie tot programul. Pentru aceasta putem proceda n felul urmtor:
C:\Mm>debug -nbeep2.com -l -a109 1393:0109 mov bx,17f 1393:010C -w Writing 00027 bytes -q C:\Mm>beep2

Toate programele realizate pn n acest moment nu conin o condiie explicit de ieire (exit). Aa c dup ce toate celelalte sarcini ale progamului au fost realizate, ieirea din program este de fapt ultimul serviciu pe care programul l cere sistemului de operare. Ieirea din program poate fi ns legat de o condiie extern, cum ar fi de exemplu apsarea unei taste. Un astfel de program continu s execute ntr-o bucl diverse sarcini pn la ndeplinirea unei condiii. Programul beep3.com prezentat n continuare este o bucl cu ieirea condiionat de apsarea unei taste (serviciul BIOS, INT 16h, AH = 01h). In cadrul acestei bucle dup scrierea la consol a caracterului BEL (07h) urmeaz o secven de ntrziere. La ieirea din bucl se afl secvena de ieire prin care este invocat funcia exit din DOS.
-a 1371:0100 mov ah,02 1371:0102 mov dl,07 1371:0104 int 21 1371:0106 mov bx,00ff 1371:0109 mov cx,ffff 1371:010C nop 1371:010D loopnz 10c 1371:010F dec bx 1371:0110 cmp bx,0000 1371:0113 jnz 109 1371:0115 mov ah,01 1371:0117 int 16 1371:0119 jz 100 1371:011B mov ax,4c00 1371:011E int 21 1371:0120 -nbeep3.com -rcx CX 0000 :20

;fixm serviciul solicitat, stare tastatur ;invocm ntrerupere BIOS, poziioneaz fanion ;dac nu este apasat tast salt la 100h ;altfel, fixm exit ;invocm ntrerupere DOS

Microprocesoare i Microcontrolere
-w Writing 00020 bytes -

43

Prin rularea acestui program putem observa c timpul dintre dou sunete nu este ntotdeauna acelai. Din analiza programului nu putem oferi o explicaie acestui fenomen. Explicaia este, fr ndoial, legat de mecanismul de ntreruperi externe. Microprocesorul nu se ocup numai de rularea programului nostru, el mai rezolv ntre timp (adic furnd din timpul programului nostru) o serie de alte taskuri/evenimente care in de funcionarea calculatorului. O comportare asemntoare poate fi observat i n alte programe care folosesc secvene de ntrziere realizate prin software. O prim etap a antrenamentului de scriere a unor programe n limbaj de asamblare este n acest moment ncheiat. Acum avem suficiente cunotiine de programare n limbaj de asamblare pentru a aborda unul din cele mai vechi circuite specializate programabile 8255 (PPI, Programmable Peripheral Interface). Acest circuit se afla fizic pe placa de baz a primelor calculatoare IBM PC. Pentru compatibilitate, funciile acestui circuit au fost preluate de circuitele moderne care tind s integreze toate circuitele clasice ntr-un singur chip. Orice circuit de periferie are un numr de port-uri, prin intermediul crora acesta schimb informaie cu exteriorul (operaii de intrare/ieire, I/O). Port-urile sunt un alt fel de locaii de memorie la care are acces att microprocesorul ct i periferia de intrare/ieire. Porturile sunt pentru microprocesor ntr-un spaiu de adrese, separat de adresele de memorie. Accesul la acest spaiu de memorie i implicit la port-uri se face prin instruciuni specifice de lucru cu acestea. De altfel, la familiile de microprocesoare dezvoltate de firma Motorola nu se face aceast distincie, aa c port-urile sunt accesate prin aceleai instruciuni care sunt utilizate pentru operaiile cu memoria. In cazul circuitului 8255 port-urile au cte 8 bii fiecare i din exterior sunt vzute ca fiind port-urile A, B i respectiv C. Port-urile A, B i C ale circuitului 8255 aflat pe Mother Board-ul unui calculator IBM PC sunt accesate prin urmtoarele adrese de port: 60h, 61h, 62h. Modul de lucru al fiecrui port (intrare, ieire sau alte funcii specifice unui protocol de transfer) este stabilit prin intermediul Registrului de Control de la adresa 63h. Circuitul 8255 este frecvent utilizat n aplicaiile de achiziie de date i control implementate cu ajutorul calculatoarelor IBM PC. Acest lucru se datoreaz att simplitii sale ct i compatibilitii cu familia 80X86 de microprocesoare. Trebuie subliniat faptul c longevitatea circuitului se datoreaz n mare parte carierei sale didactice. De altfel, exist o serie de alte circuite (produse de Motorola, Zilog, Mostek) care asigur

44

Circuite Specializate Programabile

mult mai multe funcii dect acest circuit. Nu de puine ori n acest domeniu s-a ntmplat ca cel mai utilizat circuit s nu fie neaprat i cel mai performant. 8255 este un circuit programabil de interfa paralel. El are trei pri care trebuie bine cunoscute pentru o apreciere i o utilizare corect: interfaa spre procesor, interfaa spre periferie i circuitele interne (registrele). Toate aceste componente sunt puse n eviden n figura 3.1. Transferul datelor la i de la circuit se face pe o magistrala de date organizat pe 8 bii.

D0 D1 D2 D3 D4 D5 D6 D7

PA0

PA7

PC0

8255 - PPI
PC7

/RD /WR /CS RESET

PB0

A0 A1 PB7 Registrul de Control PB7

Figura 3.1. 8255 - PPI diagrama bloc.

Protocolul transferului este asigurat de semnalele de pe magistrala de comand (CS - Chip Select , RD - ReaD, WR - WRite) respectiv magistrala de adres (A0,A1). Nu este greu s ne imaginm c numai ndeplinirea simultan a condiiilor implicate de semnalele precedente asigur activarea circuitului 8255. n acest fel, prin intermediul unor decodificatoare (hardware) pot fi accesate pe aceeai magistral de date (un numr de linii cu aceeai funcie) circuite diferite

Microprocesoare i Microcontrolere

45

aflate la adrese diferite. Interfaa cu periferia conine 24 de linii I/O. Caracteristicile i rolul liniilor de interfa sunt funcie de modul de operare care se selecteaz sub controlul programului. Toate acestea sunt sumar prezentate n tabelul 3.1. Modul 0. n modul 0, oricare din port-uri poate fi folosit fie ca registru de ieire, fie ca un registru de intrare. Modul 1. Modul intrare-ieire strobat. n acest mod, port-ul A i B utilizeaz liniile port-ului C pentru semnalele de control ale transferului (handshaking signals). Aceste semnale sunt: STB, IBF (Input Buffer Full) i INTR (Interrupt Request) pentru controlul intrrilor i OBF (Output Buffer Full), ACK (Acknowledge), INTR pentru controlul ieirilor.
Tabelul 3.1
PIN PA0 - PA7 PB0 -PB7 PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 IN * * * * * * * * * * MODUL 0 OUT * * * * * * * * * * MODUL 1 IN OUT * * * * INTRB INTRB IBFB OBFB STBB ACKB INTRA INTRA STBA * IFBA * * ACKA * OBFA MODUL 2 IN-OUT * Neutilizat I/O I/O I/O INTRA STBA IBFA ACKA OBFA

Pentru cazul n care datele vin de la periferic mpreun cu semnalul de strob (STB), acestea sunt nscrise (de STB) n registrul tampon intern semnaliznd aceasta prin semnalul IBF i INTR. Semnalul IBF poate fi folosit pentru a confirma perifericului c data a fost preluat. Tot IBF ca stare a registrului intern poate fi testat citind portul C (PC5 - IBFA, PC1 - IBFB) n vederea unui transfer programat. Semnalul INTR poate fi folosit ca o cerere de ntrerupere adresat microprocesorului pentru ca acesta s preia din 8255 data depus de periferic. Dup ce microprocesorul depune n registrele port-ului A sau B o dat destinat unui periferic, el las protocolul de transfer pe seama lui 8255. Prezena datei n port este semnalizat perifericului prin semnalul OBF care poate fi folosit i ca strob al datelor. Prin semnalul ACK, perifericul confirm circuitului 8255 preluarea datei care dezactiveaz semnalul OBF i activeaz semnalul INTR. Transferul poate fi complet sub controlul programului, prin transferarea byte cu byte n urma testrii interne a portului C (PC7 - OBFA, PC1 - OBFB) sau folosind semnalul INTR pentru a ntrerupe microprocesorul cnd perifericul este gata de a

46

Circuite Specializate Programabile

primi un nou byte. Pentru achitarea acestei cereri de ntrerupere, microprocesorul sare la subrutina care asigur depunerea unui nou byte n registrul tampon corespunztor. Modul 2. Acest mod se refer numai la grupul de linii PA7-0, linii bidirecionale (port A) i 5 linii din port-ul C. Semnalele de control ale transferului, OBF, ACK, STB, IBF i INTR sunt cele din modul 1 intrare-ieire. Acestea asigur fluena transferului bidirecional. n modul 2 port-ul A are afectate dou registre care asigur simultan o operaie de intrare i una de ieire. Dup depunerea datei n 8255 de ctre microprocesor, aceasta nu va afecta ieirile portului A. Data depus activeaz ieirile portului A numai dac perifericul dorete preluarea ei (aic activeaz semnalul ACK). Perifericul poate s nu fac preluarea ci dimpotriv, s depun o alt dat pentru microprocesor. Nici aceast dat nu va ajunge direct pe magistrala de date a microprocesorului, ci va fi zvort n registru, de unde va putea fi citit ulterior de ctre microprocesor. Modul de adresare i tipurile de operaii ale circuitului sunt prezentate n tabelul 3.2.
Tabelul 3.2
CS 0 0 0 0 0 0 0 0 1 A1 0 0 1 1 0 0 1 1 X A0 0 1 0 1 0 1 0 1 X RD 0 0 0 0 1 1 1 1 X WR 1 1 1 1 0 0 0 0 X OPERAIA Citete port-ul A Citete port-ul B Citete port-ul C Operaiune ilegal Scrie n port-ul A Scrie n port-ul B Scrie n portul C Scrie n Registrul de Control Magistrala de date trece n impedan ridicat

Programarea modului de operare se face simplu printr-un singur byte de control, cu structura prezentat n tabelul 3.3. Citirea strii port-ului C n modul 1 i 2 este util n cazul unui transfer de date dintre microprocesor i periferic sub controlul programului. Formatul byte-ului de stare este dat n tabelul 3.4. Acest mod de transfer este mai lent i de regul se utilizeaz pentru un volum relativ mic de date. Singurul avantaj al acestui mod este de natur hardware; circuitul 8255 nu este particularizat pentru o anumit aplicaie, ci este utilizat n acest caz, ca un circuit de interfa de uz general.

Microprocesoare i Microcontrolere

47

Tabelul 3.3
D7 1 Def. Mod D6 D5 Grup A, 00-MOD 0 01 - MOD 1, 1X - MOD2 D4 PA7-0 1/0-I/O D3 PC7-4 1/0-I/O D2 Grup B 1/0-I/O D1 PB7-0 1/0-I/O D0 PC3-0 1/0-I/O

n urma citirii coninutului port-ului C, noi putem cunoate starea fiecrui transfer lund n program deciziile corespunztoare.
Tabelul 3.4
D7 I/O OBFA OBFA D6 I/O INTEA INTE1 D5 IBFA I/O IBFA D4 INTEA I/O INTE2 D3 INTRA INTRA INTRA D2 INTEB INTEB I/O D1 IBFB OBFB I/O D0 INTRB INTRB I/O

MOD 1 IN MOD 1 OUT MOD 2

Circuitul 8255 asigur o serie de servicii (de exemplu, tastatur) la nivelul unui calculator IBM PC, printre acestea i activarea/dezactivarea (PB1) ieirii de sunet, dup cum se poate vedea n figura 3.2. Deoarece acest proces de activare/dezactivare modific starea logic de la ieirea porii spre difuzor (o poart AND sau NAND), noi vom putea genera un semnal dreptunghiular.
PB1 - 8255
&

Speaker

OUT2 - 8254, "1" logic Figura 3.2. Schema bloc pentru Speaker IBM PC.

Pentru ca acest semnal s fie n domeniul audio vom apela la o subrutin de ntrziere. Utiliznd comenzile utilitarului DEBUG vom scrie programul urmtor care se constituie ntr-un prim exemplu de utilizare a circuitului programabil 8255. Deoarece, n acest caz circuitul 8255 deservete mai multe periferice, interveniile

48

Circuite Specializate Programabile

noastre asupra coninutului regitrilor interni trebuie s fie minime. Acest lucru a fost realizat prin grupul de instruciuni de la adresa offset 109h - 10Dh, respectiv 112h - 116h.
-a 1371:0100 jmp 109 1371:0102 mov cx,8fff 1371:0105 nop 1371:0106 loopnz 105 1371:0108 ret 1371:0109 in al,61 1371:010B or al,02 1371:010D out 61,al 1371:010F call 102 1371:0112 in al,61 1371:0114 and al,fd 1371:0116 out 61,al 1371:0118 call 102 1371:011B mov ah,01 1371:011D int 16 1371:011F jz 109 1371:0121 mov ax,4c00 1371:0124 int 21 1371:0126 -nppi.com -rcx CX 0000 :26 -w Writing 00026 bytes ;jump la adresa de start, 109h ;subrutina de ntrziere ; ; ; ;citim valoare din port-ul B ;modificm numai PB1 - "1" logic ;scriem noua valoare n port ;apelm subrutina de ntrziere ;citim valoare din port-ul B ;modificm numai PB1 - "0" logic ;scriem noua valoare n port ;apelm subrutina de ntrziere ;fixm serviciul solicitat, stare tastatur ;invocm ntrerupere BIOS, poziioneaz fanion ;dac nu este apasat tast salt la start ;altfel, fixm exit ;invocm ntrerupere DOS

Desigur, modificarea parametrilor din subrutina de ntrziere va determina frecvena semnalului dreptunghiular generat prin aceast metod. Frecvena semnalului generat depinde de performanele calculatorului utilizat i desigur va fi modulat de intervenia altor servicii pe care microprocesorul le va executa n acelai timp. O asemenea situaie poate fi neplacut n diverse aplicaii i pe de alt parte, acest procedeu de generare a unui semnal audio este un bun exemplu de irosire a puterii microprocesorului. Pentru astfel de sarcini prezena unui circuit programabil specializat ar fi cea mai bun soluie. Acest circuit exist pe Mother Board-ul unui calculator IBM PC i se numete 8254 (PIC, Programmable Interval Counter). Acest circuit este specializat pentru generarea i contorizarea de impulsuri. Schema bloc a circuitului 8254 (compatibil cu versiunea iniial 8253, aceast versiune are performane electrice modeste) este prezentat n figura 3.3. De altfel, circuitul 8254 este mai puin versatil dect alte circuite similar

Microprocesoare i Microcontrolere

49

specializate produse de alte firme. De asemenea, ca i 8255 are merite didactice i norocul de a fi utilizat n calculatoarele IBM PC.

D0 D1 D2 D3 D4 D5 D6 D7 /RD /WR /CS CLK2 GATE2 A0 A1 PB7 Registrul de Control OUT2 CLK1 CLK0 GATE0 OUT0

8254 - PIC

GATE1 OUT1

Figura 3.1. 8254 - PIC diagrama bloc.

Circuitul 8254 are 3 numrtoare (CouNTer) de 16 bii (word) independente; fiecare din ele poate fi nscris sau citit i i se poate stabili un mod de funcionare propriu. Cele 3 numrtoare (CNT0, CNT1, CNT2) se decrementeaz la fiecare impuls extern, evitndu-se astfel decodificatoarele de coinciden. Modul de numrare poate fi n sistemul binar sau n sistemul ZCB, dup modul stabilit prin byte-ul de control. Interfaa spre microprocesor este identic cu a circuitului 8255, mai puin semnalul de RESET. Prin magistrala de date este transferat n circuit byte-ul de control, respectiv valoarea de numrat. Acest transfer are loc sub controlul liniilor din magistrala de comand i adres (CS, RD, WR, A0, A1). Adresa celor 3 numrtoare n cazul particular al unui calculator IBM PC este 40h, 41h, 42h, iar registrul de control se afl la adresa 43h.

50

Circuite Specializate Programabile

Interfaa cu periferia conine cte o linie de tact CLK, o linie GATE i o linie OUT pentru fiecare numrtor (CLK0, CLK1, CLK2, GATE0, GATE1, GATE2, OUT0, OUT1, OUT2). Dac linia de GATE este n "1" logic, atunci numrtorul respectiv este activat. Pentru fiecare numrtor, ieirea OUT indic momentul n care numrtorul a atins valoarea 0. Semnalul de ieire este specific modului n care numrtorul a fost programat s funcioneze. Fiecare numrtor are nevoie de un singur byte de control pentru a i se stabili modul de funcionare i baza de numeraie (binar sau ZCB). Deoarece adresarea este unic pentru oricare din cele trei numrtoare la care s-ar referi byteul de control, specificarea numrtorului (Counter) la care se refer este coninut n chiar structura byte-ului (D7, D6). Pentru programator este important structura byte-ului de control, aceasta este prezentat n tabelul 3.5. Modul 0. Ieirea numrtorului se pune pe "0" logic imediat dup nscrierea byteului de control, iar numrtoarea invers ncepe imediat dup nscrierea valorii n numrtor. Pe fiecare impuls de tact numrtorul se decrementeaz; la atingerea valorii 0 acesta i trece ieirea n starea "1" logic. Intrarea GATE inhib numrtoarea cnd este inut n "0" logic.
Tabelul 3.5
D7 SC1 00 - CNT0 01 - CNT1 10 - CNT2 D6 SC0 D5 D4 RL1 RL0 00 - Load word 01 - Read low byte 10 - Read high byte 11 - Read word D3 M2 000 - MOD0 001 - MOD1 010 - MOD2 011 - MOD3 100 - MOD4 101 - MOD5 D2 M1 D1 M0 D0 BCD 0 - BIN 1 - ZCB

Modul 1 (monostabil declanabil). Ieirea OUT devine "0" pe primul clock dup frontul pozitiv al intrrii GATE i rmne n aceast stare pn la terminarea numrtorii. Intrarea GATE poate fi folosit pentru redeclanarea monostabilului. Fiecare front pozitiv aplicat intrrii GATE va declana decrementarea valorii iniiale din numrtor. Dac se nscrie o nou valoare n timpul ciclului de numrare invers, aceast valoare nu va afecta ciclul n desfurare. Modul 2 (multivibrator). n acest mod, ieirea se pune la "0" pe durata unui impuls de tact (CLK) la sfritul fiecrei secvene de numrare, atta timp ct semnalul de intrare GATE rmne n "1" logic. Dac o nou valoare se nscrie n numrtor n timpul desfurrii modului 2, secvena curent de decrementare se ncheie fr nici

Microprocesoare i Microcontrolere

51

o schimbare, iar secvena urmtoare va ncepe decrermentarea de la noua valoare depus n numrtor. Modul 3 (multivibrator cu factor de umplere 1/2). Acest mod este asemntor cu cel descris anterior, deosebirea constnd n factorul de umplere. Dac valoarea iniial nscris n numrtor este par, ieirea va sta jumtate de perioad n starea "1" logic i cealalt jumtate n "0" logic, iar dac este impar va sta (N+1)/2 perioade de tact n "1" logic i (N-1)/2 perioade de tact n "0" logic. Modul 4. n acest mod, dup nscrierea valorii n numrtor ncepe decrementarea, i numai la atingerea valorii 0, ieirea trece n "0" logic pe durata unui impuls de tact. Intrarea GATE n "0" logic inhib funcionarea. Modul 5. Este asemntor cu cel descris anterior, cu observaia c un front pozitiv pe intrarea GATE va declana numrtoarea. Valoarea "0" logic pe intrarea GATE nu inhib o secven deja declanat. Cu ajutorul utilitarului DEBUG s scriem un program care s genereze un semnal dreptunghiular n domeniul frecvenelor audibile apelnd la seviciul circuitului 8254. Dup cum se poate vedea n programul urmtor, pentru acest lucru vom utiliza numrtorul de la adresa 42h. Celelalte dou numrtoare sunt utilizate pentru alte servicii de mare importan pentru funcionarea ntregului sistem (refrearea memoriei DRAM, respectiv Ceasul de sistem). De asemenea, trebuie remarcat faptul c ieirea PB0 a circuitului 8255 controleaz intrarea GATE2 a circuitului 8254. Aa c, pentru a produce un sunet n difuzor trebuie ndeplinite simultan dou condiii: poarta spre difuzor s fie deschis (PB1 n "1" logic) i intrarea GATE2 a circuitului 8254 s fie de asemenea n stare "1" logic (PB0 n "1" logic, adic numrtorul CNT2 nu este inhibat).
-a 1371:0100 1371:0102 1371:0104 1371:0106 1371:0108 1371:010A 1371:010C 1371:010E 1371:0110 1371:0112 1371:0114 1371:0116 1371:0118 1371:011A 1371:011C 1371:011E 1371:0121 1371:0123 mov al,b6 out 43,al mov al,ff out 42,al mov al,0f out 42,al in al,61 or al,03 out 61,al mov ah,01 int 16 jz 112 in al,61 and al,fc out 61,al mov ax,4c00 int 21 ;fixm byte-ul de control pentru 8254 ;scriem byte-ul de control n reg. control ;fixm i scriem n CNT2 numrul 0fffh

;citim valoarea port-ului B, 8255 ;modificm bit0,1 la "1" logic ;scriem noua valoare n port B 8255, sun! ;verificm cond. exit ;dac nu exit, salt la verific cond. exit ;altfel, citim valoarea port-ului B, 8255 ;modificm bit0,1 la "0" logic ;scriem noua valoare n port B 8255, tace! ;apel DOS exit

52
-nctc1.com -rcx CX 001D :23 -w Writing 00023 bytes -

Circuite Specializate Programabile

Rulm pas cu pas (trace) programul precedent pentru a nelege interaciunea dintre microprocesor i circuitele programabile 8254 i 8255. Pentru a evita blocarea calculatorului este recomandabil urmtoarea secven de comenzi, care implic relansarea utilitarului DEBUG.
C:\Mm>debug -nctc1.com -l -r AX=0000 BX=0000 DS=1393 ES=1393 1393:0100 B0B6 -t AX=00B6 BX=0000 DS=1393 ES=1393 1393:0102 E643 -t AX=00FF BX=0000 DS=1393 ES=1393 1393:0106 E642 -t AX=00FF BX=0000 DS=1393 ES=1393 1393:0108 B00F -t AX=000F BX=0000 DS=1393 ES=1393 1393:010A E642 -t AX=000F BX=0000 DS=1393 ES=1393 1393:010C E461 -t AX=003F BX=0000 DS=1393 ES=1393 1393:0110 E661 -t

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=0100 MOV AL,B6

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=0102 OUT 43,AL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=0106 OUT 42,AL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=0108 MOV AL,0F

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=010A OUT 42,AL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=010C IN AL,61

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=0110 OUT 61,AL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PE NC

Microprocesoare i Microcontrolere

53

n acest moment trebuie s auzim un sunet n difuzor. Cu aceast ocazie putem constata calitatea semnalului generat (stabilitatea frecvenei, tonul) i constatm c, dei pentru moment programul nu mai ruleaz (suntem n mod trace), semnalul este generat n continuare. Deoarece, de generarea semnalului cu parametri fixai (secvena de instruciuni de la adresa offset 104h - 10Ah) se ocup circuitul 8254, singura preocupare a microprocesorului este de a verifica condiia de ieire (exit) din program; apsarea unei taste (secvena de instruciuni de la adresa offset 112h - 116h). Cu urmtoarea comand srim peste subrutina serviciului BIOS, INT 16
AX=013F BX=0000 DS=1393 ES=1393 1393:0114 CD16 -t=116 CX=0023 DX=0000 SS=1393 CS=1393 INT 16 SP=FFFE IP=0114 BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PE NC

i rulm n continuare pas cu pas s vedem ce se ntmpl. n modul rulare pas cu pas lucrul cu tastatura asigur automat condiia de ieire pentru program.
AX=013F BX=0000 DS=1393 ES=1393 1393:0118 E461 -t AX=012C BX=0000 DS=1393 ES=1393 1393:011C E661 -t CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=0118 IN AL,61 BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PE NC

CX=0023 DX=0000 SP=FFFE SS=1393 CS=1393 IP=011C OUT 61,AL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

n acest moment nu mai auzim sunet n difuzor, ieirea spre acesta a fost dezactivat, iar pe intrarea GATE2 a circuitului 8254 avem n acest moment "0" logic. Spunem c numrtorul a fost inhibat. Cu urmtoarea comand trecem i peste serviciul DOS invocat de INT 21.
AX=4C00 BX=0000 DS=1393 ES=1393 1393:0121 CD21 -g CX=0023 DX=0000 SS=1393 CS=1393 INT 21 SP=FFFE IP=0121 BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Program terminated normally -

Pentru a putea atinge stadiul de novice n domeniul embedded system s exersm programarea n limbaj de asamblare, prin scrierea a dou programe care produc efecte sonore de baz. Cu puin imaginaie, putem genera un sweep tip "dinte de fierstru" (semnal cu frecvena variabil n timp). Un asemenea semnal ar putea fi, de exemplu, util n msurarea benzii de trecere a unui amplificator audio

54

Circuite Specializate Programabile

sau incint acustic. Cu ajutorul utilitarului DEBUG scriem, salvm i rulm urmtorul program:
-a 1371:0100 jmp 116 1371:0102 mov al,b6 1371:0104 out 43,al 1371:0106 mov ax,bx 1371:0108 out 42,al 1371:010A mov al,ah 1371:010C out 42,al 1371:010E ret 1371:010F mov cx,01ff 1371:0112 nop 1371:0113 loopnz 112 1371:0115 ret 1371:0116 in al,61 1371:0118 or al,03 1371:011A out 61,al 1371:011C mov bx,03ff 1371:011F mov cx,02ff 1371:0122 dec bx 1371:0123 call 102 1371:0126 push cx 1371:0127 pushf ntrziere 1371:0128 call 10f 1371:012B popf 1371:012C pop cx 1371:012D loopnz 122 1371:012F mov ah,01 1371:0131 int 16 1371:0133 jz 11c 1371:0135 in al,61 1371:0137 and al,fc 1371:0139 out 61,al 1371:013B mov ax,4c00 1371:013E int 21 1371:0140 -nctc2.com -rcx CX 0000 :40 -w Writing 00040 bytes ;salt necondiionat la start, 116h ;subrutin de initializare 8254 cu numr

; ;subrutin de ntrziere scurt

; ;start, citesc valoare port B ;activez ieire difuzor, fixm GATE2 - "1" ;fixm valoare max. numr n reg. BX ;fixm de cte ori s fie decrementat reg. BX ;decrementm BX ;apelm subrutin init. 8254 ;salvm valoarea din CX pe stiv ;idem fanioane, le distruge subrutina de ;apelm subrutina de ntrziere ;refac fanione ;refac valoarea initial din CX ;dac valoarea din reg. CX nu este zero ;salt la 122h ;verific condiia de exit ;dac nu exit atunci salt la offset 11Ch ;altfel dezactivm, inhibm

;ieire DOS

Dac modificm puin programul anterior, putem obine un sweep "triunghiular". Din pcate orice modificare implic modificarea adreselor de offset. Utilitarul DEBUG a fost conceput pentru realizarea de aplicaii simple, aplicaiile

Microprocesoare i Microcontrolere

55

scrise pentru un asamblor adevrat (MASM, TASM) sunt mult mai uor de ntreinut i/sau modificat. Pentru a nu mai complica lucrurile, vom scrie urmtorul program cu ajutorul comenzilor utilitarului DEBUG. Cu toate acestea este bine s aruncm o privire asupra diferenelor dintre cele dou programe.
-a 1371:0100 jmp 116 1371:0102 mov al,b6 1371:0104 out 43,al 1371:0106 mov ax,bx 1371:0108 out 42,al 1371:010A mov al,ah 1371:010C out 42,al 1371:010E ret 1371:010F mov cx,ffff 1371:0112 nop 1371:0113 loopnz 112 1371:0115 ret 1371:0116 in al,61 1371:0118 or al,03 1371:011A out 61,al 1371:011C mov bx,03ff 1371:011F mov cx,02ff 1371:0122 dec bx 1371:0123 call 102 1371:0126 pushf 1371:0127 push cx 1371:0128 call 10f 1371:012B pop cx 1371:012C popf 1371:012D loopnz 122 1371:012F mov cx,02ff 1371:0132 inc bx 1371:0133 call 102 1371:0136 push cx 1371:0137 pushf 1371:0138 call 10f 1371:013B popf 1371:013C pop cx 1371:013D loopnz 132 1371:013F mov ah,01 1371:0141 int 16 1371:0143 jz 11c 1371:0145 in al,61 1371:0147 and al,fc 1371:0149 out 61,al 1371:014B mov ax,4c00 1371:014E int 21 1371:0150 -nctc3.com -rcx CX 0000 ;salt necondiionat la start, 116h ;subrutin de initializare 8254 cu numr

; ;subrutin de ntrziere scurt

; ;start, citesc valoare port B ;activez ieire difuzor, fixm GATE2 - "1" ;idem secvena din cazul precedent ;decrementez reg. BX

;refac valoarea din reg. CX ;incrementez reg. BX

;idem secvena din cazul precedent

56
:50 -w Writing 00050 bytes -

Circuite Specializate Programabile

Probabil aceste dou programe ne ridic cteva probleme pentru moment. n aceast etap a cri, urmrind comentariile prezente n sursa programelor, ar trebui s nelegem modul de funcionare al acestora. Dup ce am neles programele (aplicaiile) precedente putem s ncercm alte valori de start pentru numrtorul CNT2, sau numrul de decrementri i/sau ncrementri ale valorii de start (se poate apela la rularea pas cu pas a programelor, pentru aceasta vom utiliza cu inteligen comenzile utilitarului DEBUG). Aceste modificri nu implic rescrierea programului. Desigur, valorile posibile sunt n intervalul 0000h - FFFFh, dar nu pentru toate aceste valori vom obine frecvene audibile ale semnalului generat. O alt modificare posibil este valoarea iniial a registrului CX din subrutina de ntrziere i de aceast dat jucndu-ne cu aceste programe se pot nva multe. n final, s aruncm o privire n folder-ul (director-ul) Mm, pentru a dovedi c am lucrat ceva.
C:\Mm>dir Volume in drive C is SYSTEM Volume Serial Number is 3871-17FF Directory of C:\Mm . .. ASCII HELLO CLRSCR HELLO BEEP1 BEEP2 BEEP3 CTC1 CTC2 CTC3 PPI <DIR> <DIR> TXT TXT COM COM COM COM COM COM COM COM COM 11 file(s) 2 dir(s) 02-06-00 11:36a . 02-06-00 11:36a .. 94 02-06-00 2:50p ascii.txt 13 02-06-00 8:45p HELLO.TXT 19 02-07-00 10:00p CLRSCR.COM 43 02-07-00 10:21p HELLO.COM 11 02-12-00 4:53p BEEP1.COM 39 02-12-00 7:00p BEEP2.COM 23 02-14-00 7:46p BEEP3.COM 35 02-15-00 7:10p CTC1.COM 64 02-15-00 8:12p CTC2.COM 80 02-15-00 8:11p CTC3.COM 38 02-15-00 6:53p ppi.com 459 bytes 1,987,710,976 bytes free

C:\Mm>

Cu aceast ocazie, putem vedea ct de lungi sunt programele noastre. Cel mai lung program are 80 de bytes. Dac scriem aceleai programe n limbajul C, vom nelege de ce se spune c limbajul de asamblare folosete cel mai eficient resursele

Microprocesoare i Microcontrolere

57

unui calculator. Desigur, avantajele sunt legate att de spaiul de memorie utilizat de program, ct i de viteza de rulare a acestuia. Scrierea unor aplicaii complexe n limbaj de asamblare nu este productiv, dar nu de puine ori, anumite pri din program trebuie scrise n acest limbaj. Dup cum am mai spus, marele merit al limbajului de asamblare este faptul c tim n fiecare moment ce face microprocesorul. Cu inteligen i imaginaie, nu de puine ori, reuim s realizm aplicaii care par incredibile pentru un programator care lucreaz numai cu limbaje de nivel nalt.

58

Circuite Specializate Programabile

Microprocesoare i Microcontrolere

59

4. Portul Paralel. Aplicaii Simple

Portul paralel este marele aliat al nceptorului n domeniul achiziiei de date i control. Un mare numr de astfel de "specialiti" cred cu convingere c orice aplicaie de achiziie de date i control se poate aborda prin intermediul portului paralel. Evident, acest lucru este adevrat ori de cte ori complexitatea problemei sau fluxul de date ce trebuie transferat nu depete posibilitile reale ale acestuia. Oricum, o asemenea abordare a unei probleme de achiziie de date i control se vrea ntodeauna o demonstraie de ingeniozitate. Din pcate, sufer profesia pentru fericirea "specialistului". Reuita nu face dect s demonstreze nc o dat ct de flexibil i adaptabil este aceast tehnologie i nu neaprat ct de mare este "specialistul". Trebuie recunoscut c acest att de blamat port (pn n anul 1994) are reale caliti didactice, aa c vom folosi i noi portul paralel n primul rnd pentru instruire. Nu de puine ori o abordare ingenioas, prin intermediul portului paralel, a unor probleme relativ complicate de achiziie de date i control a condus la aplicaii incitante (cu portul paralel n mod EPP sau ECP ). n concluzie, nu trebuie s avem complexe c, n acest moment, suntem novici n domeniul embedded system. Important este s nu rmnem la acest nivel. Iar experienele pe care le vom face pe portul paralel vor deveni n timp o amintire plcut a copilriei noastre n acest domeniu. Portul paralel este compus din 4 linii de control (Control Register), 5 linii de stare (Status Register), i 8 linii de date (Data Register). Toate aceste linii sunt prezente de regul pe partea din spate a carcasei PC-ului ntr-un conector de tip D25 (cu pin female, LPTx). Conectorul D25 cu pin male conine liniile portului serial RS-232 care este organizat cu totul diferit fa de portul paralel. Pn n anul 1994 portul paralel nu a fost standardizat, dei a oferit suport hardware pentru diverse periferice printer, scanner, drivere CD-ROM, camer video, etc. Lipsa de standardizare a dus n timp la multe versiuni, de implementare a portului paralel, nct este greu de spus care este comportamentul real al portului paralel pentru un calculator no-name. De asemenea tehnologia utilizat la realizarea circuitelor driver pentru portul paralel a evoluat n timp de la TTL la CMOS. De toate acestea se poate face rspunztoare firma IBM care pentru prima versiune a calculatorului IBM PC a limitat (nu cred c n mod intenionat) utilizarea portului paralel la controlul unei imprimante (Centronics). Dac portul paralel ar fi fost proiectat de la nceput pentru uz general (eventual cu transfer DMA (ECP) i faciliti de alimentare pentru hardware extern), alta ar fi fost istoria multor aplicaii.

60

Portul Paralel. Aplicaii Simple

Orice nou versiune a portului paralel asigur compatibilitatea cu versiunea iniial SPP (Standard Parallel Port) sau "Centronics Mode". n acest mod, datele sunt transferate ntr-o singur direcie, de la calculator la periferic, cu o vitez de 50 bytes/secund dar poate fi i mai mare (depinde de periferic), pn la 150 bytes/secund. Pentru a citi date de la periferic avem n versiunea SPP la dispoziie, cu siguran, modul Nibble. La unele versiuni este prezent i modul Byte, dar nu putem conta pe aceast facilitate dect la calculatoarele produse relativ recent. n anul 1994 prin standardul IEEE 1284-1994 au fost definite 5 moduri de operare. Acestea sunt:
Centronics Mode. Nibble Mode. Byte Mode. EPP Mode (Enhanced Parallel Port). ECP Mode (Extended Capabilities Printer port).

Tabelul 4.1

Pin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18-25

Signal Strobe Data 0 Data 1 Data 2 Data 3 Data 4 Data 5 Data 6 Data 7 Ack Busy Paper Out / End Select Auto Linefeed Error /Fault Initialize Select Printer Ground

In/Out Out Out Out Out Out Out Out Out Out In In In In In/Out In In/Out In/Out Gnd

Register Control Data Data Data Data Data Data Data Data Status Status Status Status Control Status Control Control

Inverted #

Microprocesoare i Microcontrolere

61

Modul de lucru pentru portul paralel este set-at n BIOS i poate fi modificat n timpul secvenei de initializare (boot). Pentru modurile EPP i ECP transferurile sunt realizate fr intervenia unor instruciuni de I/O din partea microprocesorului (viteza de transfer este de civa Mbytes/secund). Un hardware specializat asigur n acest caz protocolul de transfer, este pstrat compatibitatea cu modul SPP. Pentru a nu avea surprize neplcute (specifice calculatoarelor no-name) este bine s mizm numai pe versiunea SPP a portului paralel. Semnificaia pin-ilor portului paralel n mod SPP pentru un conector tip D25 female este prezentat n tabelul 4.1. Unele dintre liniile din registrul Status i Control sunt inversate la ieirea/intrarea din registri portului paralel. De acest lucru trebuie inut cont fie la proiectarea hardware-ului extern, sau mai simplu (fr consum de componente), la scrierea programului. Liniile din Registrul de Control ar trebui s fie de tip Open Collector (Open Drain pentru CMOS), configuraie ce permite transferul bidirecional pe aceste patru linii; cu excepia unor situaii cu totul particulare aceast regul nu este nclcat de productorii de hardware. La unele caculatoare, portul paralel este suficient de evoluat (nu se poate miza pe acest lucru) pentru a putea folosi liniile din Registrul de Date pentru transfer bidirecional. Dac acest mod este disponibil Registrul de Control trebuie set-at cu valoarea 0010xxxx pentru a putea putea efectua operaii de citire prin registrul de date. Pentru a nelege aceast ultim informaie trebuie s fim ateni la semnificaia biilor din cele trei registre ale portului paralel. Tabelul 4.2 detaliaz semnificaia fiecrui bit din aceti regitri, pentru portul paralel utilizat n modul SPP. Pentru toate programele prezentate n continuare, noi vom face abstracie de destinaia iniial a unor linii, aa c vom privi portul paralel ca un port de uz general cu 8 linii de ieire (Data Port) i patru linii de intrare (Status Port). Portul de Date sau Registrul de Date poate fi utilizat pentru a scoate date pe liniile portului paralel (Pin 2-9). n mod normal, acesta este un port numai pentru output. n aceast situaie, dac vom face o operaie de citire noi vom primi valoarea ultimului byte ncris (util n a testa hard-ul, byte-ul nscris trebuie s coincid cu cel citit, utilizm 00h i ffh pentru a testa toate liniile portului). Dac acest port este bidirecional atunci dac scriem n port 00h i facem enable bi-dir. (0010xxxx), fr a conecta nimic n port, trebuie s citim ffh. n cazul n care citim tot 00h, portul de date este unidirecional. Portul Status sau Registrul Status este un port care poate numai citi date, sunt disponibile 5 linii de intrare (Pin 10-13, 15). Portul de Control sau registrul de Control a fost proiectat cu intenia de a fi port de ieire. Avem disponibile patru linii de control pentru imprimant. De regul,

62

Portul Paralel. Aplicaii Simple

acest port este realizat fizic cu drivere Open Collector/Drain. Din acest motiv, el poate fi utilizat i ca port de intrare respectnd regula unei magistrale I cablat (vom scrie mai nti n port valoarea 00001111, adic 0fh pentru a nu falsifica datele de la intrarea portului).
Tabelul 4.2

Offset Base + 0

Name Data Port

Read/Write Write or R/W if Port is bi-dir.

Base + 1

Status Port

Read Only

Bit Number Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

Properties Data 7 Data 6 Data 5 Data 4 Data 3 Data 2 Data 1 Data 0 Busy Ack Paper Out Select In Error IRQ (Not) Reserved Reserved Unused Unused Enable bi-dir. Enable IRQ via Ack Line Select Printer Reset Auto Linefeed Strobe

Base + 2

Control Port

Read/Write

Pentru a face primele noastre experiene legate de modul n care un embedded system interacioneaz cu mediul nconjurtor, vom realiza o extensie

Microprocesoare i Microcontrolere

63

hardware care completeaz portul paralel cu elemente de execuie (semnalizare, Led-uri), respectiv posibilitatea de a introduce diverse date din exterior. Schema acestei extensii este prezentat n figura 4.1. Capabilitatea de curent a portului paralel este sczut, de aceea se nseriaz cu LED-urile resistoare cu valoarea de 470 ohmi.

Figura 4.1. Schema extensiei pentru Portul Paralel.

Pentru a nu folosi o surs extern de energie, nivelul de "1" logic la swich-urile de la Portul Status este asigurat de ieirea Data 7 via resistoarele de 3,3 kohmi (Pin 9) cu rol de separare swich-uri (raportul 470/3300 nu afecteaz prea mult valoarea potenialului din punctul comun de legtur). Aa c vom set-a bitul 7 din Portul de Date pe "1" pentru a activa partea de input a extensiei.

64

Portul Paralel. Aplicaii Simple

Pentru a vedea ce porturi paralele (pot fi dou, numite LPT1 i LPT2) avem instalate n calculatorul nostru i care este adresa lor de baz apelm la utilitarul DEBUG.
-d0000:0400 0000:0400 F8 0000:0410 23 0000:0420 30 0000:0430 64 0000:0440 00 0000:0450 00 0000:0460 0E 0000:0470 00 -d 0000:0480 1E 0000:0490 07 0000:04A0 00 0000:04B0 00 0000:04C0 00 0000:04D0 00 0000:04E0 00 0000:04F0 AA 03 C4 0B 20 00 18 0D 00 00 07 00 00 00 00 00 00 F8 00 30 30 C0 00 00 00 3E 00 00 00 00 00 00 00 02 80 0B 0B 00 00 D4 00 00 00 CE 01 00 00 00 00 00 02 30 30 00 00 03 00 18 00 00 9B 00 00 00 00 00 80 0B 0B 00 00 29 01 10 00 00 00 00 00 00 00 00 00 08 30 00 00 30 00 00 10 C0 44 0A 00 00 00 00-78 20-00 0E-0D 0B-30 00-00 00-00 A4-17 00-14 60-89 02-00 00-32 00-00 00-00 00-DC 80-07 00-2A 03 00 1C 0B 03 00 7D 14 51 00 00 00 00 04 00 00 00 2A 0D 3A 50 00 85 14 0B 00 00 05 00 00 08 A8 00 00 1C 27 00 00 04 3C C9 00 C0 00 00 00 00 00 00 2A 0D 30 00 00 D4 01 58 00 10 00 00 00 00 00 00 00 1C 0B 10 00 4B 01 01 00 10 00 00 00 00 00 00 34 E0 00 00 00 13 01 00 00 00 00 00 00 00 00 00 05 48 00 00 00 00 01 01 00 00 00 00 00 00 00 ........x....... #...... ..*.*.4. 0.0.0..........H d 0.0.0.0.:'0... ..........P..... ................ .....)0..}...K.. ...........<.... ..>....`.Q..X... ................ ........2....... ......D......... ................ ................ ................ ........*.......

Aceasta este o parte din zona de lucru a BIOS-ului, rezervat automat la iniializarea sistemului. Multe din locaiile acestei zone sunt iniializate n acest moment. Prima zon de date a BIOS-ului ncepe la adresa 0000:0400h. Datorit modului de generare a adresei fizice, aceast adres poate fi specificat sub mai multe forme, dou sunt cele mai utilizate: 0000:0400h i 0040:0000h. Aceast zon conine date i variabile utilizate de ctre BIOS, iar locaiile la care se afl acestea sunt fixate pentru a pstra compatibilitatea cu versiunile viitoare de BIOS. O parte din aceste locaii nu au coninutul specificat, ele sunt rezervate pentru viitoare evoluii ale BIOS-ului. Fr a face o descriere complet a acestei zone (poate fi cel puin subiectul unui capitol separat) reinem cteva semnificaii:
0000:0400 0000:0402 0000:0404 0000:0406 0000:0408 0000:040A 0000:040C 0000:040E 0000:0410 . . . Adresa primului port serial RS - 232, COM1. COM2 COM3 COM4 Adresa primului port paralel, LPT1 LPT2 LPT3 LPT4 Lista echipamentelor instalatate

Microprocesoare i Microcontrolere

65

Dup cum se poate vedea n cazul acestui calculator avem dou port-uri seriale (COM1, COM 2) cu adresele de baz 03F8h, 02F8 i un singur port paralel cu adresa de baz 0378h. Nu este greu s deducem adresa pentru fiecare registru al portului paralel (Tabelul 4.2). Registrul de Date va avea adresa 0378h. Coninutul Registrului Status va putea fi aflat dac citim valoarea din portul de adres 0379h, iar pentru Registrul de Control vom utiliza adresa 037Ah.

Figura 4.2. Realizarea practic a extensiei pentru Portul Paralel.

nainte de a scrie cteva programe pentru portul paralel cu extensia din figura 4.1 reinem c pentru porturile cu adresa mai mare de FFh nu mai este posibil adresarea direct (exemplu; in al,61 toate porturile de pe Mother Board au adresa mai mic sau cel mult egal cu FFh). O alt ciudenie a microprocesoarelor Intel 80x86, care a fost motenit din ani '70. Aa c, pentru adresarea porturilor cu adresa mai mare de FFh se folosete adresarea indirect prin intermediul registrului DX. Secvena de scriere n port-ul de adres 0378h este: mov dx,378 mov al, data_byte

66

Portul Paralel. Aplicaii Simple

out dx,al iar pentru citire din portul 0379h vom utiliza secvena de instruciuni: mov dx,379 in al, dx. Dup ce conectm n portul paralel (LPT1) extensia hardware prezentat n figura 4.2, lansm n execuie utilitarul DEBUG pentru a scrie urmtorul program. Atenie, putem distruge portul paralel dac placa de extensie are scurtcircuite ntre liniile Portului de Date (ieirea acestuia este Totem pole).
-a 1371:0100 jmp 117 1371:0102 mov bx,007f 1371:0105 mov cx,ffff 1371:0108 nop 1371:0109 loopnz 108 1371:010B dec bx 1371:010C cmp bx,0000 1371:010F jnz 105 1371:0111 ret 1371:0112 mov dx,378 1371:0115 out dx,al 1371:0116 ret 1371:0117 mov al,01 1371:0119 push ax 1371:011A pop ax 1371:011B call 112 1371:011E rol al,1 1371:0120 call 102 1371:0123 push ax 1371:0124 mov ah,01 1371:0126 int 16 1371:0128 jz 11a 1371:012A pop ax 1371:012B mov al,00 1371:012D call 112 1371:0130 mov ax,4c00 1371:0133 int 21 1371:0135 -npprl.com -rcx CX 0000 :35 -w Writing 00035 bytes -

Rulm programul de la consol i trebuie s obinem o lumin dinanic pe irul de Led-uri (Jumper 1-2). Dac sunt aspecte ale programului pe care nu le nelegem, e simplu, rulm programul pas cu pas (trace). n rest, nimic nou sub

Microprocesoare i Microcontrolere

67

soare. Pentru a schimba sensul de rotaie a luminii dimanice lansm n execuie utilitarul DEBUG i scriem urmtoarele comenzi:
C:\Mm>debug -npprl.com -l -u 1393:0100 EB15 1393:0102 BB7F00 1393:0105 B9FFFF 1393:0108 90 1393:0109 E0FD 1393:010B 4B 1393:010C 83FB00 1393:010F 75F4 1393:0111 C3 1393:0112 BA7803 1393:0115 EE 1393:0116 C3 1393:0117 B001 1393:0119 50 1393:011A 58 1393:011B E8F4FF 1393:011E D0C0 -a11e 1393:011E ror al,1 1393:0120 -npprr.com -w Writing 00035 bytes -

JMP MOV MOV NOP LOOPNZ DEC CMP JNZ RET MOV OUT RET MOV PUSH POP CALL ROL

0117 BX,007F CX,FFFF 0108 BX BX,+00 0105 DX,0378 DX,AL AL,01 AX AX 0112 AL,1

Obinem n final dou programe, cte unul pentru fiecare sens de rotaie. Dac viteza de baleiere a irului de LED-uri este nepotrivit, modificm valoarea de start din rutina delay (1393:0102). De asemenea, un bun exerciiu de virtuozitate este comentarea programelor precedente. n acest moment, suntem ct de ct familiarizai cu modul n care pot fi comandate (controlate) elementele de execuie externe (LED-uri, dar poate fi la fel de bine i altceva, de exemplu poate fi controlat simultan starea a opt ghilotine). Un singur pas mai avem de fcut pentru a putea s ne imaginm aplicaii complexe n care embedded system-ul preia informaii din exterior, le prelucreaz i le returneaz pentru atingerea unor obiective. Acest pas const n citirea datelor de la un periferic extern. Pe placa de extensie a portului paralel (figura 4.1) se afl 4 swich-uri cu ajutorul crora putem controla starea celor 4 linii de intrare din Portul Status. Dup cum se poate observa n figura 4.1, valoarea "1" logic este preluat din Portul de Date (Data 7, Pin 9), aa c, vom avea grij ca mai nti s set-m n "1" logic linia Data 7. Aceast relativ complicare a hardware-ului extern a fcut

68

Portul Paralel. Aplicaii Simple

posibil o mare simplificare: nu este nevoie de o surs extern de alimentare. Din tabelul 4.2 rezult c liniile de intrare le gsim n zona Bit 7 - Bit 4 a Portului Status. Aa c, pentru a nu perturba linia Data 7 din Portul de Date nainte de a returna datele citite, acestea sunt rotite la dreapta cu patru poziii. De asemenea, ne asigurm tot timpul c linia Data 7 este set-tat n "1" logic.

Figura 4.3. Schema modificarii extensiei pentru Portul Status simulat prin program.

Lasm n execuie utilitarul DEBUG i scriem programul urmtor.


-a 1393:0100 1393:0103 1393:0105 1393:0106 1393:0109 1393:010A 1393:010C 1393:010E 1393:0110 1393:0112 1393:0114 1393:0116 1393:0119 1393:011A 1393:011C 1393:011E mov dx,378 mov al,80 out dx,al mov dx,379 in al,dx and al,f0 ror al,1 ror al,1 ror al,1 ror al,1 or al,80 mov dx,378 out dx,al mov ah,01 int 16 jz 106 ;fixm portul de output ;bit-ul 7 set-at n "1" logic ;nscriu data din reg. AL n port ;fixm portul de input ;citim data din Portul Status ;mask, reinem numai 4 bii superiori ;rotim bii n zona inferioar

;set-m bitul 7 pe "1" logic, surs pt. swich ;pregtim portul de output ;noua valoare n port

Microprocesoare i Microcontrolere
1393:0120 mov 1393:0122 out 1393:0123 mov 1393:0126 int 1393:0128 -nppdr.com -rcx CX 0000 :28 -w Writing 00028 al,00 dx,al ax,4c00 21

69

bytes

Lansm n execuie programul precedent i dup cum rezult dintr-un studiu atent al schemei din figura 4.1 n paralel cu informaiile din tabelele 4.1 i 4.2, biii 6 i 7 sunt inversai ntre ei, iar bit-ul 7 este negat intern. Dac am fi realizat o schem extern dup indicaiile din figura 4.3 aceste complicaii nu ar fi aprut, numai c ar fi fost necesar un circuit inversor i o complicare inutil a cablajului. Reinem c, orice ncercare de soluionare prin hardware a unor astfel de probleme nu face dect s complice inutil lucrurile. Urmtorul program reface toate problemele legate de citirea datelor prin Portul de Status.
-a 1371:0100 1371:0103 1371:0105 1371:0106 1371:0109 1371:010A 1371:010B 1371:010C 1371:010E 1371:0110 1371:0112 1371:0114 1371:0115 1371:0117 1371:0119 1371:011B 1371:011D 1371:011E 1371:0120 1371:0122 1371:0124 1371:0126 1371:0128 1371:012A 1371:012C 1371:012F 1371:0130 mov dx,378 mov al,80 out dx,al mov dx,379 in al,dx push ax push ax not al ror al,1 and al,40 mov bl,al pop ax rol al,1 and al,80 or al,bl mov bl,al pop ax and al,30 or al,bl ror al,1 ror al,1 ror al,1 ror al,1 or al,80 mov dx,378 out dx,al mov ah,01 ;fixm portul de output ;bit-ul 7 set-at n "1" logic ;nscriu data din reg. AL n port ;fixm portul de input ;citim data din Portul Status ;copiem pe stiv ;copiem pe stiv ;negm coninutul reg. AL ;rotim spre dreapta ;mask, reinem numai bit-ul 6 ;mutm momentan valoarea n reg. BL ;refacem coninutul iniial ;rotim la stinga ;mask, reinem numai bit-ul 7 ;informaia a fost corectat pentru biii 7, 6 ;mutm momentan valoarea n reg. BL ;refacem coninutul iniial ;mask, reinem numai biii 5, 4 ;informaia a fost corectat ;rotim bii n zona inferioar

;set-m bitul 7 pe "1" logic, surs pt. swich ;pregtim portul de output ;noua valoare n port

70
1371:0132 int 16 1371:0134 jz 106 1371:0136 mov al,00 1371:0138 out dx,al 1371:0139 mov ax,4c00 1371:013C int 21 1371:013E -nppok.com -rcx CX 0000 :3e -w Writing 0003E bytes -

Portul Paralel. Aplicaii Simple

Dac lansm n execuie programul precedent, vom constata c lucrurile au revenit la o situaie cu o logic mai uor de reinut (la robinetul de ap cald curge ap cald). Cteva instruciuni n cod main au rezolvat o problem hardware. De regul, aplicaia nu are de suferit din astfel de cauze deoarece timpul n care o asemenea secven de instruciuni este executat de un calculator modern este de ordinul zecilor de nanosecunde. Deoarece putem avea unele probleme n nelegerea unor secvene din programul precedent, vom rula programul pas cu pas pentru situaia cnd toate intrrile sunt n "1" logic.
C:\Mm>debug -nppok.com -l -r AX=0000 BX=0000 DS=1393 ES=1393 1393:0100 BA7803 -t AX=0000 BX=0000 DS=1393 ES=1393 1393:0103 B080 -t AX=0080 BX=0000 DS=1393 ES=1393 1393:0105 EE -t AX=0080 BX=0000 DS=1393 ES=1393 1393:0106 BA7903 -t AX=0080 DS=1393 BX=0000 ES=1393

CX=003E DX=0000 SP=FFFE SS=1393 CS=1393 IP=0100 MOV DX,0378

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0378 SP=FFFE SS=1393 CS=1393 IP=0103 MOV AL,80

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0378 SP=FFFE SS=1393 CS=1393 IP=0105 OUT DX,AL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0378 SP=FFFE SS=1393 CS=1393 IP=0106 MOV DX,0379

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E SS=1393

DX=0379 CS=1393

SP=FFFE IP=0109

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Microprocesoare i Microcontrolere
1393:0109 EC -t AX=0078 BX=0000 DS=1393 ES=1393 1393:010A 50 -t AX=0078 BX=0000 DS=1393 ES=1393 1393:010B 50 -t AX=0078 BX=0000 DS=1393 ES=1393 1393:010C F6D0 -t AX=0087 BX=0000 DS=1393 ES=1393 1393:010E D0C8 -t AX=00C3 BX=0000 DS=1393 ES=1393 1393:0110 2440 -t AX=0040 BX=0000 DS=1393 ES=1393 1393:0112 88C3 -t AX=0040 BX=0040 DS=1393 ES=1393 1393:0114 58 -t AX=0078 BX=0040 DS=1393 ES=1393 1393:0115 D0C0 -t AX=00F0 BX=0040 DS=1393 ES=1393 1393:0117 2480 -t AX=0080 BX=0040 DS=1393 ES=1393 1393:0119 08D8 -t IN AL,DX

71

CX=003E DX=0379 SS=1393 CS=1393 PUSH AX

SP=FFFE IP=010A

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0379 SS=1393 CS=1393 PUSH AX

SP=FFFC IP=010B

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0379 SS=1393 CS=1393 NOT AL

SP=FFFA IP=010C

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0379 SP=FFFA SS=1393 CS=1393 IP=010E ROR AL,1

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0379 SP=FFFA SS=1393 CS=1393 IP=0110 AND AL,40

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO CY

CX=003E DX=0379 SP=FFFA SS=1393 CS=1393 IP=0112 MOV BL,AL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0379 SS=1393 CS=1393 POP AX

SP=FFFA IP=0114

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0379 SP=FFFC SS=1393 CS=1393 IP=0115 ROL AL,1

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=003E DX=0379 SP=FFFC SS=1393 CS=1393 IP=0117 AND AL,80

BP=0000 SI=0000 DI=0000 OV UP EI PL NZ NA PO NC

CX=003E DX=0379 SP=FFFC SS=1393 CS=1393 IP=0119 OR AL,BL

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PO NC

72
AX=00C0 BX=0040 DS=1393 ES=1393 1393:011B 88C3 -t AX=00C0 BX=00C0 DS=1393 ES=1393 1393:011D 58 -t AX=0078 BX=00C0 DS=1393 ES=1393 1393:011E 2430 -t AX=0030 BX=00C0 DS=1393 ES=1393 1393:0120 08D8 -t AX=00F0 BX=00C0 DS=1393 ES=1393 1393:0122 D0C8 -t AX=0078 BX=00C0 DS=1393 ES=1393 1393:0124 D0C8 -t AX=003C BX=00C0 DS=1393 ES=1393 1393:0126 D0C8 -t AX=001E BX=00C0 DS=1393 ES=1393 1393:0128 D0C8 -t AX=000F BX=00C0 DS=1393 ES=1393 1393:012A 0C80 -t AX=008F BX=00C0 DS=1393 ES=1393 1393:012C BA7803 -t AX=008F BX=00C0 DS=1393 ES=1393 1393:012F EE CX=003E DX=0379 SP=FFFC SS=1393 CS=1393 IP=011B MOV BL,AL

Portul Paralel. Aplicaii Simple


BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PE NC

CX=003E DX=0379 SS=1393 CS=1393 POP AX

SP=FFFC IP=011D

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=011E AND AL,30

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=0120 OR AL,BL

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=0122 ROR AL,1

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=0124 ROR AL,1

BP=0000 SI=0000 DI=0000 OV UP EI NG NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=0126 ROR AL,1

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=0128 ROR AL,1

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=012A OR AL,80

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PE NC

CX=003E DX=0379 SP=FFFE SS=1393 CS=1393 IP=012C MOV DX,0378

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PO NC

CX=003E DX=0378 SP=FFFE SS=1393 CS=1393 IP=012F OUT DX,AL

BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PO NC

Microprocesoare i Microcontrolere
-t AX=008F BX=00C0 DS=1393 ES=1393 1393:0130 B401 -g CX=003E DX=0378 SP=FFFE SS=1393 CS=1393 IP=0130 MOV AH,01 BP=0000 SI=0000 DI=0000 NV UP EI NG NZ NA PO NC

73

Program terminated normally -

Pentru o mai bun nelegere a modului de lucru a programului precedent complicm puin programul pentru a ne asigura o mai bun interacivitate cu Portul Status. Datele citite i corectate vor fi nu numai returnate n Portul de Date, ci vor fi i tiprite pe ecran n format binar. Lansm n execuie utilitarul DEBUG i realizm urmtorul program:
-a 1371:0100 1371:0102 1371:0104 1371:0106 1371:0107 1371:0109 1371:010B 1371:010D 1371:010F 1371:0110 1371:0113 1371:0115 1371:0116 1371:0119 1371:011A 1371:011B 1371:011C 1371:011E 1371:0120 1371:0122 1371:0124 1371:0125 1371:0127 1371:0129 1371:012B 1371:012D 1371:012E 1371:0130 1371:0132 1371:0133 1371:0135 1371:0137 1371:0139 1371:013B jmp 110 mov ah,02 int 21 ret mov dl,30 shl al,1 jnc 10f inc dl ret mov dx,378 mov al,80 out dx,al mov dx,379 in al,dx push ax push ax not al ror al,1 and al,40 mov bl,al pop ax rol al,1 and al,80 or al,bl mov bl,al pop ax and al,30 or al,bl push ax ror al,1 ror al,1 ror al,1 ror al,1 or al,80

;subrutina, tiprete caracter

;subrutin, fixm cod ASCII pentru "0/1" logic

;start program, identic cu programul precedent

;copiem pe stiv, urmeaz s fie tiprit ;pregtim data din reg. AL pentru port output

74
1371:013D mov dx,378 1371:0140 out dx,al 1371:0141 mov cx,0004 1371:0144 mov dl,20 1371:0146 call 102 1371:0149 pop ax 1371:014A pushf 1371:014B call 107 1371:014E popf 1371:014F push ax 1371:0150 call 102 1371:0153 loopnz 144 1371:0155 pop ax 1371:0156 mov dl,0d 1371:0158 call 102 1371:015B mov ah,01 1371:015D int 16 1371:015F jz 110 1371:0161 mov al,00 1371:0163 mov dx,378 1371:0166 out dx,al 1371:0167 mov ax,4c00 1371:016A int 21 1371:016C -nppdrv.com -rcx CX 0000 :6c -w Writing 0006C bytes -

Portul Paralel. Aplicaii Simple

;data este n port ;contor numr caractere ;n reg. DL caracterul de tiprit, blank ;tiprim blank ;refac data citit din Port Status ;copiem flag-urile pe stiv, vor fi distruse ;stabilim cod ASCII ;refac flag-urile ;copiem pe stiv, data din Port Status ;tiprim ;repetm pn mai sunt caractere ;refac stare stiv ;fac return cursor fr new line ;secvent tipic, test keyboard

;dezactivez tot din Port Data

;invocm ieire n DOS

Prile mai dificile, cu elemente de noutate sunt comentate n sursa programului. Aa c, urmrind cu atenie comentariile, nu avem probleme dificile legate de nelegerea modului de afiare pe ecran. Este bine s privim cunotiinele acumulate n acest domeniu ca un continuum (tocmai de aceea nu sunt tot felul de paragrafe), deoarece toate componentele din sistem sunt n interaciune sau pot fi puse n interaciune. Pentru a demonstra acest lucru, vom scrie un program care genereaz un sunet cu ajutorul circuitului programabil 8254. Sunetul produs de acest circuit va fi auzit n difuzor numai dac Push Button-ul de pe placa de extensie este apsat (adic avem "0" logic pe linia ACK din Portul Status). Apelnd la procedurile cunoscute de acum vom realiza, urmtorul program:
-a 1371:0100 1371:0102 1371:0104 1371:0106 mov out mov out al,b6 43,al al,ff 42,al

Microprocesoare i Microcontrolere
1371:0108 mov al,0f 1371:010A out 42,al 1371:010C mov dx,378 1371:010F mov al,80 1371:0111 out dx,al 1371:0112 mov dx,379 1371:0115 in al,dx 1371:0116 and al,40 1371:0118 jz 122 1371:011A in al,61 1371:011C and al,fc 1371:011E out 61,al 1371:0120 jmp 128 1371:0122 in al,61 1371:0124 or al,03 1371:0126 out 61,al 1371:0128 mov ah,01 1371:012A int 16 1371:012C jz 112 1371:012E in al,61 1371:0130 and al,fc 1371:0132 out 61,al 1371:0134 mov dx,378 1371:0137 mov al,00 1371:0139 out dx,al 1371:013A mov ax,4c00 1371:013D int 21 1371:013F -nppdrs.com -rcx CX 0000 :3f -w Writing 0003F bytes -

75

Rulm programul, eventual i pas cu pas, pentru a elimina problemele legate de nelegerea procedurilor care decid starea circuitului 8254 i a porii spre difuzor. Pentru a demonstra abilitatea soft-ului de a prelua unele task-uri specifice hardware, pe placa de extensie se afl i un afiaj clasic cu 7 segmente. Unul din exemplele tipice de circuit logic utilizat la translatarea de cod este decodificatorul BCD - 7 Segmente. n tabelul 4.3 este prezentat relaia dintre codul HEX (include i BCD) al numrului i codul ce trebuie nscris n Portul de Date (Pini 2-9) pentru a desena imaginea numrului. Activarea prii de input este asigurat de Data 7 n "1" logic. Lansm n execuie utilitarul DEBUG i realizm programul urmtor.
-a 1371:0100 mov dx,378 1371:0103 mov al,80 1371:0105 out dx,al

76
1371:0106 1371:0109 1371:010A 1371:010B 1371:010C 1371:010E 1371:0110 1371:0112 1371:0114 1371:0115 1371:0117 1371:0119 1371:011B 1371:011D 1371:011E 1371:0120 1371:0122 1371:0124 1371:0126 1371:0128 1371:012A 1371:012D 1371:0130 1371:0132 1371:0134 1371:0137 1371:0139 1371:013A 1371:013C 1371:013E 1371:0140 1371:0142 1371:0143 1371:0146 mov dx,379 in al,dx push ax push ax not al ror al,1 and al,40 mov bl,al pop ax rol al,1 and al,80 or al,bl mov bl,al pop ax and al,30 or al,bl ror al,1 ror al,1 ror al,1 ror al,1 mov bx,148 and ax,000f add bx,ax mov al, [bx] mov dx,378 or al,80 out dx, al mov ah,01 int 16 jz 106 mov al,00 out dx,al mov ax,4c00 int 21

Portul Paralel. Aplicaii Simple

;fixm nceputul tabelei de translatare ;ne asigurm c nu avem munere mai mari de Fh ;stabilim adresa offset n tab. translatare ;citim valoarea de la adresa din reg. BX ;ne asigurm c switch-urile sunt alimentate

;tabelul de translatare 1371:0148 db bf,86, db,cf,ee,ed,fd,87,ff,ef,f7,fc,b9,de,f9,f1 1371:0158 -npp7seg.com -rcx CX 0000 :58 -w Writing 00058 bytes -

nainte de a lansa programul n execuie, mutm Jumper-ul n poziia 2-3. n aceast situaie, orice "1" logic prezent pe liniile Data 0 - Data 6 va determina aprinderea segmentului (LED) corespunztor. Dup cum se poate observa, transalatarea codului se face pe baza unui tabel (xxxx:0148). Orice numr reprezentabil pe un nibble (4 bii) este convertit n codul

Microprocesoare i Microcontrolere

77

de la o adres format din suma dintre adresa de baz (din registrul BX) i valoarea numrului. Nimic nou, dup cum tim deja un circuit combinaional poate fi uor implementat cu ajutorul unei memorii care are un numr de linii de adres cel puin egal cu numrul variabilelor funciei date. Acum este uor de neles de ce logica cablat a rmas o ciudat realitate tehnologic a anilor '60. Nu trebuie ns s ignorm importana didactic a problemelor de logic cablat, de regul, este cel mai comod mod de a ne familiariza cu cteva elemente de logic elementar.
Tabelul 4.3

HEX 0 1 2 3 4 5 6 7 8 9 A B C D E F

COD BF 86 DB CF EE ED FD 87 FF EF F7 FC B9 DE F9 F1

Data 7 on/off 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

D6 g 0 0 1 1 1 1 1 0 1 1 1 1 0 1 1 1

D5 f 1 0 0 0 1 1 1 0 1 1 1 1 1 0 1 1

D4 e 1 0 1 0 0 0 1 0 1 0 1 1 1 1 1 1

D3 d 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 0

D2 c 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0

D1 b 1 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0

D0 a 1 0 1 1 0 1 1 1 1 1 1 0 1 0 1 1

n acest moment, alfabetizarea o putem considera practic ncheiat (doar n patru capitole). O mic finisare a cunotiintelor anterioare n paralel cu abordarea unor aplicaii complexe ne va asigura o cultur minim n acest domeniu. S nu uitm de limbajul C, numai pentru o mai bun instruire eventual situaii limit n unele aplicaii complexe vom apela la limbajul de asamblare. Toate exerciiile din acest curs legate de familia de microprocesoare 80x86 pot fi scrise i n limbajul C. Atenie, acestea vor fi rulate n mod consol (un bun mediu de lucru, gratuit pe Internet, este LCC). Un astfel de program destinat depanrii i/sau testrii unor

78

Portul Paralel. Aplicaii Simple

aplicaii cu circuite FPGA (Field Programmable Gate Array) este prezentat la sfritul acestui capitol. Programul AXSPORT.EXE este destinat unui sistem de dezvoltare (XS40), care conine un circuit FPGA i un microcontroler din familia 8051 Intel, produs de firma Xess Ltd. Programul este o extensie interactiv a programului XSPORT.EXE al firmei Xess Ltd. i reine o istorie recent a evenimentelor de la pinii de intrare a circuitului FPGA. De asemenea, este pstrat compatibilitatea 100% cu programul XSPORT.EXE al firmei Xess Ltd. Versiunea compilat a programului poate fi testat cu ajutorul extensiei din figura 4.1. Liniile Data 0 i Data 1 sunt conectate prin intermediul unor inversoare la circuitul FPGA din sistemul de dezvoltare XS40 al firmei Xess Ltd. Aa c, ceea ce vedem pe ecran nu este valoarea nscris n Portul de Date, ci este valoarea de la pini de intrare ai circuitului FPGA. Dac scriem aplicaii pentru Windows xxxx (Visual C, Visual Basic) s nu uitm c utilizarea portului paralel ca port de uz general este posibil numai prin ncrcarea unui driver software destinat acestui scop. Vom gsi cteva gata scrise pe Internet, cele mai puin performante chiar n versiune freeware. Deoarece unele versiuni ale sistemului de operare Windows xxxx permit trecerea microprocesorului n situaii excepionale n mod Real (compatibilitate 100% cu MS-DOS) vom gsi multe aplicaii n care portul paralel este utilizat ca un port de uz general. Lucrul direct cu porturile sub sistemul de operare Windows NT sau Linux se supune unor reguli mai stricte. Deoarece, micropocesorul nu lucreaz n mod Real, pentru aceste sisteme de operare este indicat, pe ct posibil, s ocolim astfel de situaii n care porturile standard de comunicaie (paralel, serial) sunt utilizate ca porturi de uz general.

Microprocesoare i Microcontrolere
/******************************* ** Advanced XSPORT ** Version: 1.0 ** Date: May 05, 2000 ** Copyright 2000 by Ioan Burda ** Revision: 0 *******************************/ #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <ctype.h> #include <string.h> #include <math.h> /* variable */ unsigned short lpt_port; unsigned int data_port; unsigned int val_port; unsigned int h5_val; unsigned int h4_val; unsigned int h3_val; unsigned int h2_val; unsigned int h1_val; unsigned int s_out; /* stamp */ void d_text(void) { printf("\n AXSPORT Ver. 1.0\n"); printf(" Advanced XSPORT for XS40 and XS95 Boards\n"); printf(" (c) 2000 by Ioan Burda\n\n"); printf(" Usage: axsport [-a] [-p 2] [b7...b0]\n\n"); printf(" BIT : 7 6 5 4 - 3 2 1 0\n\n\n\n\n\n\n\n\n\n"); } /* dec printf bin */ void bin_p (void) { char lpt; unsigned int hbin; unsigned int i; unsigned int j; unsigned int val_bin; gotoxy(wherex(),wherey() - 9); lpt = '1'; if (lpt_port == 0x278) lpt='2'; for (j=1; j<7; j++) { switch(j) { case 1: if (h5_val == 0x1ff) { printf (" x x x x - x x x x"); textcolor(2); if (s_out == 2) textcolor(10);

79

80

Portul Paralel. Aplicaii Simple


if (s_out == 0) textcolor(12); printf(" [S]trobe\n"); textcolor(7); continue; } else { textcolor(7); val_bin = h5_val; printf(" # -5: "); textcolor(3); } break; case 2: if (h4_val == 0x1ff) { printf (" x x x x - x x x continue; } else { textcolor(7); val_bin = h4_val; printf(" # -4: "); textcolor(2); } break; case 3: if (h3_val == 0x1ff) { printf (" x x x x - x x x textcolor(2); if (s_out == 3) textcolor(10); printf(" [A]lways\n"); textcolor(7); continue; } else { textcolor(7); val_bin = h3_val; printf(" # -3: "); textcolor(3); } break; case 4: if (h2_val == 0x1ff) { printf (" x x x x - x x x continue; } else {

x\n");

x");

x\n");

Microprocesoare i Microcontrolere
textcolor(7); printf(" # -2: "); val_bin = h2_val; textcolor(2); } break; case 5: if (h1_val == 0x1ff) { printf (" x x x x - x x printf(" [C]ounter_up -> [D]own\n"); continue; } else { textcolor(7); val_bin = h1_val; printf(" # -1: "); textcolor(3); } break; case 6: textcolor(7); val_bin = val_port; P80 P81 P52 P51 - P50 P48 P47 P46\n"); P34 P32 P49 P48 - P47 P46 P45 P44\n"); printf(" # 0: "); textcolor(10); if(s_out == 2) textcolor(12); break; } hbin = 128; for (i=1; i<9; i++) { if (val_bin/hbin >= 1) { printf(" 1 "); val_bin = val_bin - hbin; } else { printf(" 0 "); } hbin = hbin/2; if (i == 4) printf("- "); } 4) printf("\n"); 2) printf("\n"); 1) { textcolor(2); if (s_out == 2) textcolor(10); if (s_out == 0) textcolor(12);

81

x");

printf(" XS95: printf(" XS40:

if(j == if(j == if(j ==

82
printf(" [S]trobe\n"); textcolor(3);

Portul Paralel. Aplicaii Simple

} if(j == 3) { textcolor(2); if (s_out == 3) textcolor(10); printf(" [A]lways\n"); textcolor(3); } if(j == 5) { textcolor(7); printf(" [C]ounter_up -> [D]own\n"); } if (j == 6) { textcolor(7); printf(" HEX: "); textcolor(10); if (s_out == 2) textcolor(12); printf("%02X ",val_port); textcolor (7); printf(" LPT: %c \n",lpt); printf(" KEYS: [E] [R] [T] [Y] - [U] [I] [O] [P] [W] [Q]uit\n"); } } textcolor(7); } /* advanced xsport*/ void a_choice(void) { char ch; val_port = _inp(lpt_port)^0x03; do { if (data_port == val_port && s_out == 2) s_out = 0; if (data_port != val_port && s_out == 0) s_out = 2; if(data_port != val_port && s_out != 0 && s_out != 2) { h5_val=h4_val; h4_val=h3_val; h3_val=h2_val; h2_val=h1_val; h1_val=data_port; data_port = val_port; _outp(lpt_port,data_port^0x03); val_port = data_port; if (s_out == 1) s_out = 0; } bin_p(); ch = getch(); ch = toupper(ch);

Reverse

Microprocesoare i Microcontrolere
switch(ch) { case 'E': val_port = val_port^0x80; break; case 'R': val_port = val_port^0x40; break; case 'T': val_port = val_port^0x20; break; case 'Y': val_port = val_port^0x10; break; case 'U': val_port = val_port^0x08; break; case 'I': val_port = val_port^0x04; break; case 'O': val_port = val_port^0x02; break; case 'P': val_port = val_port^0x01; break; case 'C': val_port = val_port + 1; if (val_port == 256) val_port = 0; break; case 'D': if (val_port == 0) val_port = 255; val_port = val_port - 1; break; case 'S': if (s_out == 3) s_out = 0; if (s_out == 2) s_out = 1; break; case 'A': s_out = 3; break; case 'W': val_port = val_port^0xff; break; case 'Q': exit(0); } } while (1); } /* xsport option */ void x_choice (char *s_bits) {

83

84

Portul Paralel. Aplicaii Simple


int i; int s_len; data_port = 0; s_len = strlen(s_bits); for (i= 0; i < s_len;i++) { if(s_bits[s_len - 1 - i] == '1') data_port = data_port + pow(2,i); if(s_bits[s_len - 1 - i] != '1' && s_bits[s_len - 1 - i] != '0') exit(0); } _outp(lpt_port,data_port^0x03); data_port = 0x1ff;

} /* main */ void main (int argc, char *argv[]) { h5_val = 0x1ff; h4_val = 0x1ff; h3_val = 0x1ff; h2_val = 0x1ff; h1_val = 0x1ff; data_port = 0x1ff; s_out = 1; if(argc == 1) { lpt_port = 0x378; d_text(); a_choice(); } if(argc == 2) { if(!strcmp(argv[1],"-a")) { lpt_port = 0x378; d_text(); a_choice(); } lpt_port = 0x378; x_choice(argv[1]); } if(argc == 3) { if(!strcmp(argv[1],"-p") && !strcmp(argv[2],"2")) { lpt_port = 0x278; d_text(); a_choice(); } if(!strcmp(argv[1],"-a")) { lpt_port = 0x378; d_text(); x_choice(argv[2]);

Microprocesoare i Microcontrolere
a_choice(); } } if(argc == 4) { if(!strcmp(argv[1],"-p") && !strcmp(argv[2],"2")) { lpt_port = 0x278; x_choice(argv[3]); } if(!strcmp(argv[1],"-a") && !strcmp(argv[2],"-p") && !strcmp(argv[1],"2")) { lpt_port = 0x278; d_text(); a_choice(); } } if(argc == 5) { if(!strcmp(argv[1],"-a") && !strcmp(argv[2],"-p") && !strcmp(argv[3],"2")) { lpt_port = 0x278; d_text(); x_choice(argv[4]); a_choice(); } } }

85

86

Portul Paralel. Aplicaii Simple

Microprocesoare i Microcontrolere

87

5. Programe Rezidente n Memorie

Evoluia sistemelor de operare din ultimul timp n particular evoluia sistemului de operare Windows xxxx a determinat ca anumite stiluri clasice de programare s fie, n prezent, mai puin utilizate. Trebuie reinut nc de la nceput faptul c manevrarea unei ntreruperi externe rmne o procedur standart n domeniul achiziiei de date i al controlului. Atingerea nivelului de novice n domeniul embedded system implic o practic minim legat de ntreruperile hardware respectiv rezidena programelor n memorie. Deoarece, de regul, prin astfel de programe (aplicaii) sistemele de operare Microsoft cad prad unor programe virus i dat fiind caracterul didactic al acestui capitol, vom evita pe ct posibil acele exemple care nu fac cinste "breslei". Aa c noi vom reruta ntreruperile (prin intermediul tabelei vectorilor de ntrerupere) cu cele mai nobile intenii, pentru a nva prin descoperire. nainte de a ne lansa n cteva aventuri tipice acestui domeniu (atenie sunt foarte mari anse de a bloca sistemul, vom face un fel de operaie pe creier), s vedem care sunt informaiile de care are nevoie sistemul de operare pentru putea lansa n execuie un program. Programele pe care n mod general le acceptm ca fiind programe executabile sunt cele cele de tip ".COM" i ".EXE". Din cauza spaiului de memorie segmentat al microprocesoarelor 80X86 i a faptului c instruciunile JMP i CALL (de salt respectiv apel de procedur) lucreaz cu adrese relative, oricare tip de program poate fi ncrcat i executat n memorie la orice adres de segment. Astfel, un program poate fi fcut resident n memorie i n continuarea lui poate fi ncrcat un alt program pentru a fi executat. Programele nu sunt niciodat scrise n ideea de a fi ncrcate la o anumit adres (cu excepia unor programe care se autoncarc). Formatul ".COM" al unui fiier este imaginea binar a datelor i a codului unui program. Fiierul trebuie s fie mai mic de 64 Kbyte i nu vor fi fcute relocri ale adreselor de segment. Formatul ".EXE" al unui fiier conine un antet cu informaii folosite de ncrctorul sistem pentru a executa ajustrile la referinele de segmente (relocri) n momentul ncrcrii. Pentru a putea nelege ceva din filosofia sistemului de operare MS-DOS legat de modul de ncrcare i execuie a programelor, vom analiza pentru nceput formatul *.COM care ne ateptm s fie mai simplu. Formatul ".COM" definete un singur segment (sau cel puin nu face referine explicite la un alt segment). Programul de tip ".COM" este ncrcat n memorie ncepnd cu adresa PSP (Program Segment Prefix):0100h. Un program de tip ".COM" poate utiliza mai multe segmente, dar trebuie s calculeze adresele pentru celelalte segmente, lund

88

Programe Rezidente n Memorie

ca referint PSP-ul de baz. Programele de tip ".COM" ocup mai puin spaiu pe disc, se ncarc mai rapid n memorie i au o structur mult mai simpl dect cele de tip ".EXE". Dup cum este uor de bnuit, aceast simplitate le face de multe ori mult mai vulnerabile la un atac din exterior asupra sistemului (virus). ncrcarea n memorie a unui program de tip ".COM" este urmat de set-area regitrilor CS, ES, DS, SS cu valoarea adresei PSP-ului de baz. Registrul SP este set-at cu o valoare corespunztoare sfritului segmentului PSP (FFFFh). Toat memoria sistem (640 Kbyte) de dup segmentul programului este alocat programului. Un cuvnt 0000h este ncrcat pe stiv, iar registrul IP este set-at cu valoarea 0100h. PSP este construit ncepnd de la adresa offset 0000h pn la 0100h (adic primii 256 de bytes), iar de la adresa offset 0100h ncepe programul. PSP-ul are urmtoarea structur:
0000h 0002h 0004h 0005h Instruciune pentru INT 20. Memoria total n segmente. Rezervat. Opcod-uri pentru FAR CALL la DOS.

000Ah Adresa rutinei de exit (IP, CS), pentru refacerea vectorului INT 22h la terminarea programului. 000Eh Adresa CTRL/Break (IP, CS), pentru refacerea vectorului INT 23h la terminarea programului. 0012h Adresa rutinei de eroare critic (IP, CS), pentru refacerea vectorului INT 24h la terminarea programului. 0016h 002Ch 002Eh Rezervai (22 de bytes). Adresa de segment a mediului DOS. Rezervai (46 de bytes).

005Ch Primul FCB (File Control Block) dup cum rezult din primul parametru al liniei de comand. 006Ch Al doilea FCB (File Control Block) dup cum rezult din al doilea parametru al liniei de comand. 0080h 0081h Lungime linie de comand (bytes). Linia de comand (parametrii).

Prin parametru se nelege orice ir de caractere din linia de comand (separatorul fiind spaiul), cu excepia comenzii propriu-zise. Blocurile care ncep la 005Ch i 006Ch sunt construite pe baza primilor doi parametri tastai dup comand. Deoarece toate programele scrise de noi pn acum sunt de tip ".COM", cu ajutorul utilitarului DEBUG putem vedea zona PSP a unui astfel de program.
C:\Mm>debug -npp7seg.com -l -d0 1393:0000 CD 20 00 A0 00 9A F0 FE-1D F0 4F 03 F6 0C 8A 03 1393:0010 F6 0C 17 03 F6 0C E5 0C-01 01 01 00 02 FF FF FF

. ........O..... ................

Microprocesoare i Microcontrolere
1393:0020 1393:0030 1393:0040 1393:0050 1393:0060 1393:0070 -d 1393:0080 1393:0090 1393:00A0 1393:00B0 1393:00C0 1393:00D0 1393:00E0 1393:00F0 -d 1393:0100 1393:0110 1393:0120 1393:0130 1393:0140 1393:0150 1393:0160 1393:0170 FF F6 07 CD 53 20 0A 00 00 00 00 00 00 00 BA 24 08 01 B0 FF 87 2A FF 0C 0A 21 45 20 50 00 00 00 00 00 00 00 78 40 D8 C3 00 EF 65 00 FF 14 00 CB 47 20 50 00 00 00 00 00 00 00 03 88 D0 8A EE F7 E3 83 FF 00 00 00 20 20 37 00 00 00 00 00 00 00 B0 C3 C8 07 B8 FC 2A 06 FF 18 00 00 20 20 53 00 00 00 00 00 00 00 80 58 D0 BA 00 B9 2E 5F FF 00 00 00 43 20 45 00 00 00 00 00 00 00 EE D0 C8 78 4C DE 43 E2 FF 93 00 00 4F 20 47 00 00 00 00 00 00 00 BA C0 D0 03 CD F9 43 01 FF-FF 13-FF 00-00 00-00 4D-00 20-00 2E-43 00-00 00-00 00-00 00-00 00-00 00-00 00-00 79-03 24-80 C8-D0 0C-80 21-BF F1-80 83-06 5B-C3 FF FF 00 00 00 00 4F 00 00 00 00 00 00 00 EC 08 C8 EE 86 3E 5F 57 FF FF 00 00 00 00 4D 00 00 00 00 00 00 00 50 D8 BB B4 DB 5D E2 8B FF FF 00 00 00 00 0D 00 00 00 00 00 00 00 50 88 48 01 CF E2 02 3E 82 00 00 00 00 00 00 00 00 00 00 00 00 00 F6 C3 01 CD EE 00 C7 5B 13 00 00 50 20 00 00 00 00 00 00 00 00 00 D0 58 25 16 ED 75 87 E2 5E 00 00 50 20 00 00 00 00 00 00 00 00 00 D0 24 0F 74 FD 0D 65 AC 3E 00 00 37 20 00 00 00 00 00 00 00 00 00 C8 30 00 C6 87 C7 E3 AA

89
..............^> ................ ................ .!...........PP7 SEG COM..... ........ .PP7SEG.COM..... ................ ................ ................ ................ ................ ................ ................ .x.....y..PP.... $@..X..$.....X$0 ...........H.%.. .....x........t. .....L.!........ .........>]..u.. .e.*.CC.._....e. *..._..[.W.>[...

Dac structura PSP-ului pentru un format de tip ".COM" este ct se poate de simpl, dup cum vom vedea n continuare nu acelai lucru se poate spune i despre antetul unui fiier de tip ".EXE". Formatul de tip ".EXE" al programelor permite utilizarea mai multor segmente de program, incluznd segmentele de cod, date i stiv. Fiierul de tip ".EXE" este ncrcat n memorie ncepnd cu adresa PSP:0100h. Pe msur ce este ncrcat, sunt preluate unele informaii din antetul fiierului pentru a se realiza relocarea. Pentru a vedea coninutul fisierului axsport.exe vom face o copie de lucru a acestuia pe care o vom redenumi axsport.txt (rename axsport.exe axsport.txt). Putem ncerca s deschidem fiierul axsport.txt cu ajutorul editorului NOTEPAD, dar mult mai util este informaia pe care o putem obine cu ajutorul utilitarului DEBUG:
C:\Mm>debug -naxsport.txt -l -d 1371:0100 4D 1371:0110 B8 1371:0120 00 1371:0130 00 1371:0140 0E 1371:0150 69 1371:0160 74

5A 00 00 00 1F 73 20

90 00 00 00 BA 20 62

00 00 00 00 0E 70 65

03 00 00 00 00 72 20

00 00 00 00 B4 6F 72

00 00 00 00 09 67 75

00-04 00-40 00-00 00-00 CD-21 72-61 6E-20

00 00 00 00 B8 6D 69

00 00 00 00 01 20 6E

00 00 00 00 4C 63 20

FF 00 00 80 CD 61 44

FF 00 00 00 21 6E 4F

00 00 00 00 54 6E 53

00 00 00 00 68 6F 20

MZ.............. ........@....... ................ ................ ........!..L.!Th is program canno t be run in DOS

90
1371:0170 -d 1371:0180 1371:0190 1371:01A0 1371:01B0 1371:01C0 1371:01D0 1371:01E0 1371:01F0 -

Programe Rezidente n Memorie


6D 6F 64 65 2E 0D 0D 0A-24 00 00 00 00 00 00 00 50 60 00 00 01 00 00 00 45 02 0C 30 00 70 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 4C E0 00 00 00 00 00 10 01 00 02 00 00 04 10 00 05 02 00 40 00 00 00 00 00-9D 01-0B 00-CB 00-00 00-04 00-00 00-00 00-00 76 01 11 10 00 00 00 00 18 01 00 00 00 00 10 00 39 03 00 00 00 00 00 00 6C 00 00 00 00 03 00 00 31 1C 10 02 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 mode....$....... PE..L....v.9l1.. `............... ................ .0....@......... ................ .p.............. ................ ................

Dac pentru noi coninutul acestui fiier pare lipsit de sens, nu acelai lucru l putem spune pentru sistemul de operare. Aa c, s vedem n continuare care este semnificaia coninutului unui antet de fiier de tip ".EXE":
0h (offset-ul se refer la fiierul de tip *.EXE i nu la program) Semntura programelor *.EXE (MZ). 2h 4h 6h 8h Lungimea paginii pariale de la sfrit (PARTPAG). Lungimea n pagini de 512 bytes, inclusiv antetul (PAGECNT. Numrul nregistrrilor din tabela de relocare (RELOCNT). Dimensiunea antetului n paragrafe (de 16 bytes, HDRSIZE).

0Ah Minimul de memorie necesar pentru program (n paragrafe, MINMEM). 0Ch Maximul de memorie necesar dup program (n paragrafe, MAXMEM). 0Eh Deplasamentul pentru segmentul de stiv (RELOSS). 10h Valoarea pentru registrul SP la lansare (EXESP). 12h Suma de control fiierului, CHKSUM). a fiierului (suma negativ a tuturor cuvintelor

14h Valoarea registrului IP la lansarea n execuie (EXEIP). 16h Deplasamentul pentru segmentul de cod (RELOCS). 18h Deplasamentul primei nregistrri de relocare (TBLEOFF). 1Ah Numrul de suprapuneri (OVERLAY). 1Ch Dimensiunea poriunii formatate a antetului *.EXE (4 bytes).

Lansarea n execuie a unui program implic crearea unui PSP cu ajutorul funciei MS-DOS 26h, urmat de citirea a 1Ch bytes din fiierul de tip ".EXE" ntro zon de memorie local. Etapa de iniializare i relocare implic determinarea modulului de ncrcat (stabilit de relaia = ((PAGECNT*512) - (HDRSIZE*16)) PARTPAG), urmat de stabilirea deplasamentului modulului de ncrcat (dimantet*16). Alegerea unei adrese de segment START_SEG pentru ncrcare (uzual, PSP + 10h) este urmat de citirea modulului de ncrcat n memorie la adresa START_SEG:0000h. Urmeaz poziionarea pointerului fiierului la nceputul tabelei de relocare, iar pentru fiecare nregistrare de relocare sistemul de operare va efectua urmtoarele operaii:

Microprocesoare i Microcontrolere

91

se citete nregistrarea ca dou cuvinte (words) de 16 bii (I_OFF, I_SEG); se adun RELO_SEG = (START_SEG + I_SEG); se determin astfel adresa de relocare; se citete cuvntul de la adresa RELO_SEG:I_OFF; se adun START_SEG la acest cuvnt (fixarea segmentului); se ncarc suma obinut napoi la adresa original (RELO_SEG:I_OFF).

nainte de a lansa programul n execuie se aloc memorie pentru program n concordan cu MINMEM i MAXMEM, se iniializeaz regitrii i se execut programul dup parcurgerea urmtorilor pai:
ES = DS = adresa PSP; se ncarc AX pentru a indica validitatea identificatorului unitii din linia de comand; SS = START_SEG +RELOSS, SP = EXESP; CS = ETART_SEG +RELOCS, IP = EXEIP.

Pentru a suplini n parte faptul c sistemul de operare MS-DOS este monotasking (ceea ce nseamn c un singur program poate rula la un moment dat), acesta permite ca un program la terminare s rmn rezident n memoria intern. Pentru acest program se aloc o zon de memorie, de regul mult mai mic dect memoria disponibil (altfel rezidena nu ar mai avea nici un sens). Accesul la resursele soft rmase rezidente se poate face prin mecanismul ntreruperilor de orice fel. Rezidena unui program n memorie se poate face n mai multe moduri. Cel mai performant mod const n invocarea funciei DOS 31h prin ntreruperea umbrel INT 21h. Aceasta primete ca argument n registrul DX numrul de paragrafe (16 bytes) ce urmeaz s rmn rezidente, fa de nceputul programului, restul eliberndu-se n vederea ncrcrii altor aplicaii. O alt posibilitate pe care, de altfel, o vom utiliza i noi, este s apelm la o metod tradiional INT 27h (n registrul DX se specific ultima adres a poriunii care se aloc +1). n general, un program rezident este format din dou pri: o parte de iniializare, care, de regul, nu rmne rezident i de aceea este plasat la sfritul programului, i o parte ce rmne rezident n memorie. O subrutin rmas rezident n vederea tratrii unei ntreruperi o vom numi handle-r. Canalul 0 al circuitului programabil 8254 (prezentat n capitolul 3) este ceas de timp real n calculatorul IBM PC. Acest canal este programat s genereze o ntrerupere hard la fiecare 54 de ms (de 18.2 ori pe secund), iar subrutina de tratare a acestei ntreruperi este parte a sistemului de operare MS-DOS. Reinem pentru moment c sistemul lucreaz cu unitatea de timp de 54 ms numit "tick", care este convertit n uniti uzuale (secunde, minute, ore) doar pentru confortul nostru. Pentru acest lucru este implementat un contor n memorie la adresa 0000:0046C pe

92

Programe Rezidente n Memorie

o lungime de patru bytes. Pentru a vedea la lucru acest serviciu al sistemului de operare MS-DOS n utilitarul DEBUG tastm urmtoarele comenzi:
-d0000:046c 0000:0460 0000:0470 00 0000:0480 1E 0000:0490 07 0000:04A0 00 0000:04B0 00 0000:04C0 00 0000:04D0 00 0000:04E0 00 -d0000:046c 0000:0460 0000:0470 00 0000:0480 1E 0000:0490 07 0000:04A0 00 0000:04B0 00 0000:04C0 00 0000:04D0 00 0000:04E0 00 21 01 58 00 10 00 00 00 53 01 01 00 10 00 00 00 06 01 00 00 00 00 00 00 00 01 01 00 00 00 00 00 !S.. ...........<.... ..>....`.Q..X... ................ ........2....... ......D......... ................ ................ ............ .T.. ...........<.... ..>....`.Q..X... ................ ........2....... ......D......... ................ ................ ............

00 00 07 00 00 00 00 00

00 3E 00 00 00 00 00 00

00 00 00 CE 01 00 00 00

00 18 00 00 9B 00 00 00

01 10 00 00 00 00 00 00

00 00 10 C0 44 0A 00 00

00-14 60-89 02-00 00-32 00-00 00-00 00-DC 80-07

14 51 00 00 00 00 04 09

14 0B 00 00 05 00 00 08

3C 89 00 C0 00 00 00 00

00 00 07 00 00 00 00 00

00 3E 00 00 00 00 00 00

00 00 00 CE 01 00 00 00

00 18 00 00 9B 00 00 00

01 10 00 00 00 00 00 00

00 00 10 C0 44 0A 00 00

00-14 60-89 02-00 00-32 00-00 00-00 00-DC 80-07

14 51 00 00 00 00 04 09

14 0B 00 00 05 00 00 08

3C 89 00 C0 00 00 00 00

88 01 58 00 10 00 00 00

54 01 01 00 10 00 00 00

06 01 00 00 00 00 00 00

00 01 01 00 00 00 00 00

Desigur vor fi alte valori, important este ns c ele se modific n permanen. n plus fa de incrementarea contorului de timp, rutina de gestiune a acestei ntreruperi mai are cteva funcii. Astfel, prin intermediul acestui serviciu vor fi oprite motoarele unitii de dischet, dac aceasta nu a mai fost accesat o perioad de timp, sau mult mai important pentru noi este apelul unei subrutine utilizator cu vectorul de ntrerupere 1Ch (INT 1Ch) care de regul conine numai instruciunea IRET (ntoarcere din ntrerupere). Aceast facilitate de nseriere a unei subrutine utilizator cu vectorul la adresa 1Ch va fi exploatat n continuare. Pentru nceput, s ne convingem c nu avem deja instalat o astfel de subrutin (alta dect aceea care conine numai instruciunea IRET). Lansm utilitarul DEBUG i afim pe ecran zona cu vectorii de ntrerupere.
-d0000:0000 0000:0000 9E 0000:0010 65 0000:0020 00 0000:0030 6F 0000:0040 07 0000:0050 39 0000:0060 A4 0000:0070 1D 0F 04 00 EF 00 E7 E7 00 C9 70 00 00 70 00 00 00 00 00 C8 F0 C8 F0 F0 C8 65 54 28 6F 4D 40 2F A4 04 FF 00 EF F8 02 00 F0 70 00 66 00 00 0B 27 00 00-16 F0-88 08-6F F0-9A F0-41 02-2D 09-6E F0-22 00 80 EF 00 F8 04 FE 05 66 00 00 66 00 70 00 00 08 F0 F0 08 F0 00 F0 00 65 6F 6F 65 7F 28 04 93 04 EF EF 04 25 0A 06 49 70 00 00 70 A7 51 51 00 00 F0 F0 00 FD 02 02 C0 ....e.p...f.e.p. e.p.T.......o... ....(.f.o...o... o...o.....f.e.p. ..p.M...A....%.. 9...@...-.p.(.Q. ..../.'.n.....Q. ........"....I..

Microprocesoare i Microcontrolere

93

Nu este greu s citim de aici adresa subrutinei cu vectorul de la adresa 4*1Ch = 70h (C800:001D), dar este mult mai simplu cu urmtoarea comand:
-d0:70 L 4 0000:0070 1D 00 00 C8 ....

Dezasamblm n continuare de la adresa rutinei de tratare a ntreruperii 1Ch i obinem:


-uc800:001d C800:001D EA53FF00F0 C800:0022 090D C800:0024 150101 C800:0027 050709 C800:002A 0B25 C800:002C 27 C800:002D 292B C800:002F 7F7F C800:0031 7F7F C800:0033 7F7F C800:0035 7F7F C800:0037 7F7F C800:0039 7F7F C800:003B 7F7F JMP OR ADC ADD OR DAA SUB JG JG JG JG JG JG JG F000:FF53 [DI],CX AX,0101 AX,0907 SP,[DI] [BP+DI],BP 00B0 00B2 00B4 00B6 00B8 00BA 00BC

urmnd indicaiile din program facem i noi un salt la adresa F000:FF53 cu ajutorul urmtoarei comenzi:
-uf000:ff53 F000:FF53 CF F000:FF54 60 F000:FF55 1E F000:FF56 B84000 F000:FF59 50 F000:FF5A 1F F000:FF5B B001 F000:FF5D 86060001 F000:FF61 3C01 F000:FF63 746F F000:FF65 FB F000:FF66 B3FF F000:FF68 B402 F000:FF6A 33D2 F000:FF6C CD17 F000:FF6E 80E4A0 F000:FF71 795C IRET DB PUSH MOV PUSH POP MOV XCHG CMP JZ STI MOV MOV XOR INT AND JNS

60 DS AX,0040 AX DS AL,01 AL,[0100] AL,01 FFD4 BL,FF AH,02 DX,DX 17 AH,A0 FFCF

94

Programe Rezidente n Memorie

unde se poate observa instruciunea IRET. Pe un alt calculator aceast aventur cu siguran va fi diferit, acesta fiind "blestemul" compatibilitii. n concluzie, nu avem o subrutin utilizator care s fi schimbat rutarea normal a acestei ntreruperi din sistemul MS-DOS (instruciunea JMP F000:FF53 este un pseudo-vector de ntrerupere, nu comentm aceast situaie). Pentru a vedea la lucru cunotiinele acumulate pn n prezent, s scriem un program cu ajutorul utilitarului DEBUG care sa rmn rezident. Acest program rezident (handler) va fi activat de "tick" (INT 1Ch) i va verifica dac este apsat push-button-ul de pe placa de extensie din portul paralel. Dac acest push-button va fi apsat, va genera un semnal sonor pn la eliberarea acestuia. Deoarece programul este rezident, el va crea impresia funcionrii n paralel cu alte programe, dar din pcate este numai o impresie.
-a 1371:0100 1371:0102 1371:0103 1371:0104 1371:0107 1371:0109 1371:010A 1371:010D 1371:010E 1371:0110 1371:0112 1371:0114 1371:0116 1371:0118 1371:011A 1371:011C 1371:011E 1371:0120 1371:0122 1371:0123 1371:0124 1371:0125 1371:0128 1371:012A 1371:012C 1371:012E 1371:012F 1371:0130 1371:0131 1371:0134 1371:0137 1371:0138 1371:013B 1371:013C 1371:013E jmp 125 push ax push dx mov dx,378 mov al,80 out dx,al mov dx,379 in al,dx and al,40 jz 11a in al,61 and al,fc out 61,al jmp 122 in al,61 or al,03 out 61,al jmp 104 pop dx pop ax iret mov ax,0000 mov es,ax mov ax,cs mov ds,ax pushf cli es: mov [0072],ax mov ax,0102 es: mov [0070],ax popf mov al,b6 out 43,al ;salt la adresa de start ;nceput handler,salvez starea reg. ;care vor fi utilizai ;fixm linia D7 n "1" logic, surs

;secvena test push-button

;salt la 11Ah dac este apsat ;altfel, nchid poarta spre difuzor

;salt la 122h, pentru exit hamdler ;deschid poarta spre difuzor

;salt la 104h, test pentru push-button ;refac starea reg. utilizai ;return din ntrerupere ;aici ncepe efectiv programul ;ES < 0000h, prima pagin de memorie ;pagina curent n AX ;pagina curent n DS ;pe stiv starea curent a fanion-elor ;dezactivm ntreruperile ;valoarea reg. AX la adresa 0000:0072 ;AX adresa de nceput handler ;valoarea reg. AX la adresa 0000:0070 ;refac starea fanion-elor ;pregtesc 8254 pentru generare sunet

Microprocesoare i Microcontrolere
1371:0140 mov 1371:0142 out 1371:0144 mov 1371:0146 out 1371:0148 mov 1371:014B int 1371:014D mov 1371:0150 int 1371:0152 -nticks.com -rcx CX 0000 :52 -w Writing 00052 al,ff 42,al al,0f 42,al dx,0125 27 ax,4c00 21

95

;reg. DX offset sfrit handler ;s rmn resident ;invocm ieire n DOS

bytes

Ne putem convinge de buna funcionare a programului anterior, dac l lansm n execuie de la prompterul MS-DOS. Aparent nu se ntmpl nimic, numai c, dac apsm pe push-button-ul de pe extensia portului paralel, vom constata c programul nostru este rezident n memorie i verific (de 18.2 ori pe secund) starea liniei ACK din portul paralel. Pentru a vedea unde s-a instalat n memorie acest program, vom apela la utilitarul DEBUG, aa c vom tasta urmtoarele comenzi:
C:\Mm>debug -d0:70 l4 0000:0070 02 01 E4 0C -u0ce4:0102 0CE4:0102 50 0CE4:0103 52 0CE4:0104 BA7803 0CE4:0107 B080 0CE4:0109 EE 0CE4:010A BA7903 0CE4:010D EC 0CE4:010E 2440 0CE4:0110 7408 0CE4:0112 E461 0CE4:0114 24FC 0CE4:0116 E661 0CE4:0118 EB08 0CE4:011A E461 0CE4:011C 0C03 0CE4:011E E661 0CE4:0120 EBE2 -u 0CE4:0122 5A 0CE4:0123 58 0CE4:0124 CF 0CE4:0125 B80000 0CE4:0128 8EC0

.... PUSH PUSH MOV MOV OUT MOV IN AND JZ IN AND OUT JMP IN OR OUT JMP POP POP IRET MOV MOV AX DX DX,0378 AL,80 DX,AL DX,0379 AL,DX AL,40 011A AL,61 AL,FC 61,AL 0122 AL,61 AL,03 61,AL 0104 DX AX AX,0000 ES,AX

96
0CE4:012A 0CE4:012C 0CE4:012E 0CE4:012F 0CE4:0130 0CE4:0131 0CE4:0133 0CE4:0135 0CE4:0137 0CE4:0138 0CE4:013B 0CE4:013C 0CE4:013E 0CE4:0140 0CE4:0141 8CC8 8ED8 9C FA 4D 0A0D 1100 0201 26 A37000 9D B0B6 E643 54 4D MOV MOV PUSHF CLI DEC OR ADC ADD ES: MOV POPF MOV OUT PUSH DEC AX,CS DS,AX

Programe Rezidente n Memorie

BP CL,[DI] [BX+SI],AX AL,[BX+DI] [0070],AX AL,B6 43,AL SP BP

Programul anterior nu face apel la funcii ale sistemului de operare pentru procedurile de rerutare a vectorului de ntrerupere sau pentru a asigura rezidena programului. Au fost preferate aceste metode pentru c sunt mult mai didactice, lsnd celui care programeaz libertatea de a controla n fiecare moment ce instruciuni execut efectiv microporcesorul. Dup cum se poate vedea, vectorul pentru ntreruperea 1Ch a fost modificat, iar la noua adres gsim n memorie handler-ul scris de noi. Cte glume de prost gust se pot face exploatnd aceast stil de programare Am putea scrie un handler care s conin o secven delay, aa c de 18.2 ori pe secund caculatorul ar pierde ceva timp de fiecare dat i utilizatorul va observa c n mod inexplicabil calculatorul ruleaz mai ncet. Dar mai bine s ne imaginm lucruri utile care cu siguran vor fi mult mai multe dect putem crede la prima vedere. La fiecare apsare a unei taste, aciunea este semnalizat BIOS-ului prin intermediul unei ntreruperi de tip 09h (INT 9h). Aceast ntrerupere este frecvent redirectat cu scopuri mai puin nobile. Se pot face multe glume de prost gust cum ar fi: dezactivarea unor taste, modificarea semnificaiei normale a acestora sau scrierea automat a unui text "enervant" la tastarea unei combinaii prestabilite. Cu ajutorul comenziilor din utilitarul DEBUG noi vom realiza un program care va redirecta ntreruperea 09h pentru a genera un "beep" la apsarea unei taste. Subrutina original este apelat din acest nou handler prin intermediul unui instruciuni CALL FAR la o adres salvat n corpul handler-ului la adresa offset 104h - 106h. nainte de lansarea n execuie la aceast adres offset a handler-ului este o adres fictiv (cafe:bece) care are doar scopul de a trasmite spre asamblorul din utilitarul DEBUG o instruciune corect. Comentariile din cadrul programului urmtor sunt suficiente pentru a nelege modul de lucru a unui astfel de handler.
-a

Microprocesoare i Microcontrolere
1396:0100 1396:0102 1396:0103 1396:0108 1396:0109 1396:010A 1396:010B 1396:010C 1396:010E 1396:0110 1396:0112 1396:0115 1396:0118 1396:0119 1396:011B 1396:011E 1396:0120 1396:0122 1396:0124 1396:0126 1396:0127 1396:0128 1396:0129 1396:012A 1396:012D 1396:012F 1396:0131 1396:0133 1396:0134 1396:0135 1396:0136 1396:0139 1396:013C 1396:013D 1396:0140 1396:0143 1396:0145 1396:0146 1396:0149 1396:014C 1396:014D 1396:0150 1396:0151 1396:0153 1396:0155 1396:0157 1396:0159 1396:015B 1396:015D 1396:0160 1396:0162 1396:0165 1396:0167 jmp 12a pushf call cafe:bece sti push ax push bx push cx in al,61 or al,03 out 61,al mov bx,001f mov cx,ffff loopnz 118 dec bx cmp bx,0000 jnz 115 in al,61 and al,fd out 61,al pop cx pop bx pop ax iret mov ax,0000 mov es,ax mov ax,cs mov ds,ax pushf cli es: mov ax,[0024] mov [0104],ax es: mov ax,[0026] mov [0106],ax mov ax,cs es: mov [0026],ax mov ax,0102 es: mov [0024],ax popf mov al,b6 out 43,al mov al,ff out 42,al mov al,0f out 42,al mov dx,012a int 27 mov ax,4c00 int 21

97
;salt la start program, peste handler ;handler, salvez stare fanions (IRET). ;call handler original ;activm ntreruperile ;salvez starea reg. utilizai

;deschid poarta spre difuzor

;secvena delay, ct dureaz sunetul

;nchid poarta spre difuzor

;refac starea reg. distrui

;return din ntrerupere ;aici ncepe programul, secvena de ;iniializare reg. ES, DS

;pe stiv starea curent a fanion-elor ;dezactivm ntreruperile ;n AX adresa handler original INT 09h ;adresa call ,,, la adresa original

;voloarea din CS n AX ;adresa noului handler n tabela ;vectorilor de ntrerupere

;refac starea fanion-elor ;pregtesc 8254 pentru generare sunet

;reg. DX offset sfrit handler ;s rmn resident ;invocm ieire n DOS

98
-nkeys.com -rcx CX 0000 :67 -w Writing 00067 bytes -

Programe Rezidente n Memorie

Pentru a putea vedea ce se ntmpl la lansarea n execuie a programului precedent scriem n continuare urmtoarea secven de comenzi n cadrul utilitarului DEBUG.
C:\Mm>debug -nkeys.com -l -d0:24 l4 0000:0020 -u 1393:0100 EB28 1393:0102 9C 1393:0103 9A28006608 1393:0108 FB 1393:0109 50 1393:010A 53 1393:010B 51 1393:010C E461 1393:010E 0C03 1393:0110 E661 1393:0112 BB1F00 1393:0115 B9FFFF 1393:0118 E0FE 1393:011A 4B 1393:011B 83FB00 1393:011E 75F5 -t AX=0000 BX=0000 DS=1393 ES=1393 1393:012A B80000 -t AX=0000 BX=0000 DS=1393 ES=1393 1393:012D 8EC0 -t AX=0000 BX=0000 DS=1393 ES=0000 1393:012F 8CC8 -t AX=1393 BX=0000

28 00 66 08 JMP PUSHF CALL STI PUSH PUSH PUSH IN OR OUT MOV MOV LOOPNZ DEC CMP JNZ 012A cafe:bece AX BX CX AL,61 AL,03 61,AL BX,001F CX,FFFF 0118 BX BX,+00 0115

(.f.

CX=0067 DX=0000 SP=FFFE SS=1393 CS=1393 IP=012A MOV AX,0000

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0067 DX=0000 SP=FFFE SS=1393 CS=1393 IP=012D MOV ES,AX

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0067 DX=0000 SP=FFFE SS=1393 CS=1393 IP=012F MOV AX,CS

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0067

DX=0000

SP=FFFE

BP=0000

SI=0000

DI=0000

Microprocesoare i Microcontrolere
DS=1393 ES=0000 1393:0131 8ED8 -t AX=1393 BX=0000 DS=1393 ES=0000 1393:0133 9C -t AX=1393 BX=0000 DS=1393 ES=0000 1393:0134 FA -t SS=1393 CS=1393 IP=0131 MOV DS,AX NV UP EI PL NZ NA PO NC

99

CX=0067 DX=0000 SS=1393 CS=1393 PUSHF

SP=FFFE IP=0133

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

CX=0067 DX=0000 SS=1393 CS=1393 CLI

SP=FFFC IP=0134

BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

AX=1393 BX=0000 CX=0067 DX=0000 DS=1393 ES=0000 SS=1393 CS=1393 1393:0135 26 ES: 1393:0136 A12400 ES:0024=0028 -t AX=0028 BX=0000 CX=0067 DS=1393 ES=0000 SS=1393 1393:0139 A30401 DS:0104=0028 -t DX=0000 CS=1393

SP=FFFC IP=0135

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC MOV AX,[0024]

SP=FFFC IP=0139

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC MOV [0104],AX

AX=0028 BX=0000 CX=0067 DX=0000 DS=1393 ES=0000 SS=1393 CS=1393 1393:013C 26 ES: 1393:013D A12600 ES:0026=0866 -t AX=0866 BX=0000 CX=0067 DS=1393 ES=0000 SS=1393 1393:0140 A30601 DS:0106=0866 -t DX=0000 CS=1393

SP=FFFC IP=013C

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC MOV AX,[0026]

SP=FFFC IP=0140

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC MOV [0106],AX

AX=0866 BX=0000 CX=0067 DX=0000 SP=FFFC DS=1393 ES=0000 SS=1393 CS=1393 IP=0143 1393:0143 8CC8 MOV AX,CS -u100 1393:0100 EB28 JMP 012A 1393:0102 9C PUSHF 1393:0103 9A28006608 CALL 0866:0028 1393:0108 FB STI 1393:0109 50 PUSH AX 1393:010A 53 PUSH BX 1393:010B 51 PUSH CX 1393:010C E461 IN AL,61 1393:010E 0C03 OR AL,03

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PO NC

100
1393:0110 1393:0112 1393:0115 1393:0118 1393:011A 1393:011B 1393:011E -g E661 BB1F00 B9FFFF E0FE 4B 83FB00 75F5 OUT MOV MOV LOOPNZ DEC CMP JNZ 61,AL BX,001F CX,FFFF 0118 BX BX,+00 0115

Programe Rezidente n Memorie

Program terminated normally -d0:24 l4 0000:0020 02 01 93 13 -q

....

Orice comemntariu este de prisos n acest moment. O serie de transformri pot fi observate att n corpul programului ct i n tabela vectorilor de ntrerupere.

D0 D1 D2 D3 D4 D5 D6 D7 IR0 IR1 IR2 INTA INT

8259

IR3 IR4 IR5 IR6 IR7

/RD /WR /CS

CAS0 A0 SP CAS1 CAS2

Figura 5.1. Diagrama bloc a circuitului 8259.

De asemenea, o atenie deosebit trebuie s acordm fanionul-ui de ntrerupere. Orice redirectare din tabela vectorilor de ntrerupere este precedat de dezactivarea tuturor ntreruperilor, pe perioada necesar redirectrii. Despre utilitatea portului paralel n aplicaii simple de achiziie de date i control cred c acum suntem

Microprocesoare i Microcontrolere

101

convini. Aria aplicaiilor i implicit calitatea acestora ar crete dac ar fi posibil lansarea unei ntreruperi hard prin intermediul portului paralel. Calculatorul ar rula diverse programe i la apariia unui eveniment extern (generat de un fenomen fizic de exemplu) se va genera o ntrerupere care va activa handler-ul specific unei aplicaii date. Microprocesorul va fi astfel implicat n procesul de achiziie de date i control numai atunci cnd prezena lui este necesar. Dac nu ar exista aceast posibilitate microprocesorul ar trebui s ruleze ntr-o bucl infinit n corpul crei-a tot timpul va testa ndeplinirea unei condiii (ar fi un mod ineficient de utilizare a microprocesorului). Lansarea unei ntreruperi hard din portul paralel este posibil. nelegerea unui asemenea handler implic studierea mecanismului (hard-ului) prin care un semnal extern (nivel logic) devine semnal de ntrerupere (INT) pentru microprocesor. Deoarece microprocesoarele au, o singur linie de ntrerupere supervizarea mai multor posibile surse de intrerupere, respectiv ierarhizarea lor n raport cu un criteriu de prioritate este lsat n sarcina unui circuit specializat, controler-ul de ntreruperi programabil, 8259. Circuitul 8259 (figura 5.1) este un controler de ntreruperi programabil. Un singur circuit poate trata pn la 8 cereri de ntrerupere, rezolvnd i problemele de prioritate aferente. Legnd n cascad (CAS0, , CAS2) mai multe astfel de circuite se pot trata pn la 64 cereri de ntrerupere. ntr-un calculator compatibil IBM PC sunt dou astfel de circuite. Cererile de ntrerupere se pot masca n mod individual. n figura 5.1 sunt prezentate conexiunile exterioare ale circuitului sub forma unei diagrame bloc. Programarea circuitului const n trimiterea spre acesta a unor cuvinte de comand. Pregtirea circuitului pentru operare se face cu ajutorul unor cuvinte de iniializare (ICW). Caracteristicile funcionale ale circuitului se stabilesc prin intermediul unor cuvinte de comand (OCW). Tot prin intermediul acestora poate fi citit i starea circuitului. n tabelul 5.1 se prezint n rezumat programarea circuitului, respectiv citirea strii sale. De asemenea, s reinem secvena obligatorie, EOI (End Of Intereupt); mov al,20 out 20,al prin care circuitul este ntiinat c ntreruperea a fost procesat de ctre handler. Dup secvena EOI circuitul este gata s solicite atenia microprocesorului pentru o alt ntrerupere. Noua ntrerupere transmis microprocesorului va fi selectat funcie de prioritatea ntreruperii (dat de modul de cablarea a circuitului 8259) respectiv coninutul registrului de mascare a ntreruperilor.

102

Programe Rezidente n Memorie


Tabelul 5.1

A0 0 1 0 0 0 1 X X

D4

D3

1 0 0 X X X

X 1 1 X X X

RD 0 0 1 0 1 1 1 X

WR 1 1 0 0 0 0 1 X

CS 0 0 0 0 0 0 0 1

Operaii Citete registrele IRR, ISR Citete registrul de mascare Depune ICW1 Depune OCW2 Depune OCW3 Depune OCW1, ICW2 sau ICW3 D0-D7 sunt trecute n SIR D0-D7 sunt trecute n SIR

Aceste informaii sunt suficiente pentru a realiza un program care s activeze linia ACK din portul paralel pentru ntreruperea IRQ7. Utiliznd comenziile utilitarului DEBUG realizm urmtorul program care va rmne rezident i va fi activat prin internediul liniei ACK - IRQ7 din portul paralel (capitolul 4, tabelul 4.2).
-a 1371:0100 1371:0102 1371:0103 1371:0104 1371:0105 1371:0106 1371:0107 1371:0108 1371:010B 1371:010D 1371:010E 1371:0111 1371:0114 1371:0117 1371:0119 1371:011A 1371:011D 1371:011F 1371:0120 1371:0122 1371:0124 1371:0127 1371:0129 1371:012A 1371:012C 1371:012E 1371:012F jmp 135 cli pushf push ax push bx push cx push dx mov dx,0378 mov al,ff out dx,al mov dx,379 mov bx,00ff mov cx,ffff loopnz 117 dec bx cmp bx,0000 jnz 114 in al,dx cmp al,38 jz 0111 mov dx,378 mov al,00 out dx,al mov al,20 out 20,al pop dx pop cx ;salt la start program, peste handler ;aici ncepe handler, rmne resident

;ntrziere pentru a elimina zgomotele ;electrice generate de push-button

;secvena EOI

Microprocesoare i Microcontrolere
1371:0130 pop bx 1371:0131 pop ax 1371:0132 popf 1371:0133 sti 1371:0134 iret 1371:0135 mov ax,0000 ;secvena redirectare IRQ7 1371:0138 mov es,ax 1371:013A mov ax,cs 1371:013C mov ds,ax 1371:013E pushf 1371:013F cli 1371:0140 es: 1371:0141 mov [003e],ax 1371:0144 mov ax,0102 1371:0147 es: 1371:0148 mov [003c],ax 1371:014B popf 1371:014C mov dx,16e ;secvena mesaj display 1371:014F mov ah,09 1371:0151 int 21 1371:0153 mov dx,37a ;secvena activare IRQ7 1371:0156 in al,dx 1371:0157 or al,10 1371:0159 out dx,al 1371:015A in al,21 ;secvena de mask-are ntreruperi 1371:015C and al,7f 1371:015E out 21,al 1371:0160 mov al,20 ;secvena EOI 1371:0162 out 20,al 1371:0164 mov dx,0135 ;secvena resident 1371:0167 int 27 1371:0169 mov ax,4c00 ;secvena exit DOS 1371:016C int 21 1371:016E db 0a,0d,"verme la lucru",0a,0d,0a,0d,"$" 1371:0183 -nverme.com -rcx CX 0000 :83 -w Writing 00083 bytes -

103

Comentariile din corpul programului asigur nelegerea modului de lucru a acestui handler. Pe timpul ct acest hadler este activ, activitatea sistemului este oprit, deoarece toate ntreruperile sunt dezactivate (CLI). Este un bun exemplu de programare agresiv a sistemului, practic pe timpul rulrii handlerului sistemul "este la mna noastr". Pentru o bun nsuire a acestor tehnici agresive de programare pot fi imaginate de fiecare dintre noi programe interesante. S le vedem la lucru.

104

Programe Rezidente n Memorie

Microprocesoare i Microcontrolere

105

6. Perioada i Frecvena unui Semnal Extern

Realizarea unor programe prin intermediul crora s pot fi determinai parametrii fizici (perioad, frecven) ai unui semnal extern este un bun antrenament pentru o situaie real din domeniul achiziiei de date i control. Deoarece sistemul de operare Windows xxxx este de tip multitasking, pentru o bun funcionare a programelor din acest capitol, calculatorul trebuie s fie restartat n modul MSDOS. Aceast trecere n modul MS-DOS simplific procedurile de tratare a ntreruperilor, ceea ce duce la posibilitatea realizrii programelor din aceast capitol, apelnd numai la elementele sistemului de operare. ntr-un mediu de programare evoluat, se pot scrie programe identice funcional care s poat rula sub un sistem de operare performant, numai c, noi vom apela i de aceast dat la serviciile oferite de utilitarul DEBUG, care desigur sunt minimale. Este bine s reinem c scopul tuturor programelor este numai acela de a nva cteva proceduri standard, ntr-un mod interactiv, cu utilizarea minimal a facilitilor sistemului de operare. Desigur c, programele sunt dezvoltate, de regul, cu ajutorul unui mediu specializat i dedicat fiecrui limbaj de programare de nivel nalt. Programarea orientat pe obiecte i mediile "Visual" au adus unelte noi, extrem de eficiente, cu ajutorul crora programatorul poate realiza relativ uor aplicaii aparent sofisticate. Cu toate acestea, orice mediu de programare permite scrierea unei pri din program (sau cel puin permite inserarea unor subrutine, inline) n limbaj de asamblare. Acest lucru este necesar ori de cte ori nu se poate altfel, adic, atunci cnd performanele impuse de aplicaie nu pot fi atinse prin programarea n limbaj de nivel nalt. Trebuie reinut c marele merit al limbajului de asamblare este acela c programatorul tie exact ce instruciune va executa microprocesorul n fiecare moment i de ct timp va fi nevoie pentru a executa instruciunea respectiv. Desigur, acest stil de programare nu este frecvent ntlnit i este legat de instrumentaia virtual, de supervizarea n timp real a unor procese externe i/sau prelucrarea n timp real a informaiei. Acestea sunt tocmai acele aplicaii specifice domeniilor experimentale din fizic. Aa c, aceast carte nu are alt scop dect acela de a specializa pe cei familiarizai cu cel puin un limbaj de nivel nalt (preferabil C), cu stilul de programare i cteva proceduri specifice domeniului embedded system. Nivelul de specializare pe care-l putem atinge prin aceste programe este, din pcate, cel de novice deoarece tehnologiile digitale sunt att de dezvoltate n prezent (i n plin dezvoltare), nct este nevoie de un efort considerabil pentru a nva la nivel de avansat, chiar i numai tehnologiile specifice unui subdomeniu. Acest lucru

106

Perioada i Frecvena unui Semnal Extern

se datoreaz, pe de o parte, complexitii i specializrii componentelor hardware i pe de alt parte, evoluiei i specializrii mediilor de lucru i limbajelor de programare generate de noile tehnologii. Pentru nceput, va trebui s realizm un dispozitiv extern (hardware) care s genereze un semnal ai crui parametrii fizici i vom determina cu ajutorul unor programe scrise n limbaj de asamblare. Plecnd de la experiena pe care o avem cu portul paralel, vom completa modulul de extensie a portului paralel prezentat n capitolul patru cu un generator de semnal dreptunghiular (figura 6.1).
DATA 7 P IN 14

10uF

0.1uF 82k 39k

22nF 5K6 100K

CD4011 68k 3k3 P IN 14 10k 10k BC547

ACK

Figura 6.1. Schema generatorului de semnal dreptunghiular.

Deoarece pentru modulul de extensie din portul paralel nu este utilizat o surs extern de alimentare i aceast facilitate vrem s o pastrm i n continuare, vom utiliza un circuit integrat realizat n tehnologie CMOS (CD4011, patru pori NAND cu dou intrri). Aceste circuite au un consum redus de energie, aa c, vom putea utiliza i de aceast dat un semnal de ieire al portului paralel (Data 7) drept surs de energie. De asemenea, pentru a putea adapta acest modul la orice situaie particular de implementare (sau obinut n urma operaiilor de setare-iniializare) a portului paralel, vom utiliza la ieirea generatorului de semnal dreptunghiular o

Microprocesoare i Microcontrolere

107

configuraie de tip open-collector (colectorul n gol). Frecvena (perioada) semnalului poate fi modificat (din poteniometrul de 100k) n limite rezonabile (numai n domeniul audio), astfel nct, dup ce vom cunoate parametri fizici ai semnalului extern, s putem face i o evaluare a performanelor calculatorului pe care rulm programele din aceast carte. Dup cum se poate vedea n figura 6.1, noul modul de extensie prin intermediul unui jumper asigur o facil adaptare a extensiei hardware la tipul de program ce urmeaz a fi implementat. Realizarea practic a acestei noi pri a modulului de extensie este prezentat n figura 6.2, aceasta a fost interconectat cu modulul de extensie iniial, formnd astfel o unitate hardware extern care acoper o mare parte din programele prezentate n primele ase capitole din aceast carte.

Figura 6.2. Realizarea practica a generatorului de semnal dreptunghiular.

Pentru a putea acoperi o arie larg de aplicaii, altele dect cele prezentate n aceast carte, semnalul dreptunghiular este aplicat pe linia ACK a portului paralel. Deoarece parametrii externi (RC) ai generatorului de semnal dreptunghiular (realizat cu circuitul integrat CD4011) fixeaz domeniul frecvenelor generate la

108

Perioada i Frecvena unui Semnal Extern

spectrul audio, ne punem problema dac semnalul extern produs de generatorul de semnal dreptunghiular nu poate fi auzit n difuzorul calculatorului. La o prim evaluare, acest lucru pare imposibil, deoarece nu putem realiza o legtur fizic ntre ieirea generatorului de semnal dreptunghiular (conectat la portul paralel) i difuzor, fr a interveni distructiv n cablarea iniial a calculatorului IBM PC. Dup cum deja tim, difuzorul este conectat fizic la circuitul 8254 prin intermediul unei pori controlate (PB1) cu ajutorul circuitului 8255. n unul din primele noastre programe de producere a unui sunet n difuzorul calculatorului am generat sunetul din difuzor prin controlul strii porii de la ieirea OUT2 a circuitului 8254. Tot prin intermediul circuitului 8255 (PB0) numrtorul (CNT2) era blocat prin fixarea strii pentru intrarea GATE2 n "0" logic. Dac vom reui s controlm poarta spre difuzor, sincron cu starea semnalului extern produs de generatorul de semnal dreptunghiular, atunci vom reproduce n difuzor chiar acest semnal. Realizarea unui program care s captureze starea liniei ACK din portul paralel (379h pentru LPT1) i s o transfere pe linia PB1 (61h) a circuitului PPI 8255 nu este o sarcin dificil la nivelul actual de competen. Nu trebuie s uitm nici un moment c generatorul de semnal dreptunghiular este alimentat cu energie din linia de ieire Data 7 a portului paralel (378h pentru LPT1). Aa c, apelnd la comenzile utilitarului DEBUG vom realiza i rula urmtorul program:
-a 1371:0100 1371:0103 1371:0105 1371:0106 1371:0109 1371:010A 1371:010C 1371:010E 1371:0110 1371:0112 1371:0114 1371:0116 1371:0117 1371:0119 1371:011A 1371:011C 1371:011E 1371:0120 1371:0122 1371:0124 1371:0126 1371:0128 1371:012A 1393:012C 1393:012F mov dx,378 mov al,80 out dx,al mov dx,379 in al,dx and al,40 ror al,1 ror al,1 ror al,1 ror al,1 ror al,1 push ax in al,61 pop bx and al,fd or al,bl out 61,al mov ah,01 int 16 jz 100 in al,61 and al,fd out 61,al mov dx,378 mov al,00 ;alimentm generatorul de semnal

;citim starea curent a liniei ACK ;reinem numai aceast informaie ;o aducem n pozitia PB1, 8255

;reimen starea curent a portului 61h ;preparm noul coninit pentru port 61h ;starea liniei ACK copit n portul 61h ;verificm keyboard ;dac nu este tasta apasat relum ;altfel facem pregtirile pt. exit

Microprocesoare i Microcontrolere
1393:0131 out 1393:0132 mov 1393:0135 int 1393:0137 -nppados.com -rcx CX 0000 :37 -w Writing 00037 dx,al ax,4c00 21

109

bytes

Modificnd frecvena semnalului generat (din poteniometrul de 100k) ne vom convinge att de buna fucionare a programului, ct i de eficiena metodei utilizate. Dac n locul semnalului produs de generatorul de semnal dreptunghiular vom conecta un semnal provenit de la un montaj, ce conine un microfon urmat de un amplificator-limitator, n difuzor vom auzi sunetele produse n faa microfonului. Metoda utilizat, de eantionare pe un bit, este suficient de puternic pentru a reda vocea uman inteligibil. Chiar i o analiz sumar a acestui program pune n dificultate experiena noastr legat de materialitatea unui semnal fizic (exprimat sub forma: u = U(t) sau i = I(t)). Cunotinele noastre clasice de electricitate i/sau electronic, n care totul era msurabil i palpabil, sunt incapabile s explice prin relaii fizice uzuale acest transfer de semnal. Nu avem un suport material clasic, n sensul proprietii unor materiale de a fi bune conductoare de curent electric, pentru acest transfer. n programul precedent, prin eantionarea semnalului dreptunghiular din portul de intrare, reinem o informaie referitoare la starea semnalului n acel moment ("0" sau "1" logic ). Ulterior, prin transferul acestei informaii ntr-un port de ieire, semnalul este refcut n forma iniial. Faptul c un semnal fizic poate exista pentru un moment (practic orict de lung) sub form de informaie despre semnalul fizic este principiul de baz al procesrii digitale a semnalelor. Acest salt de la realitatea material, palpabil i primitiv, la un univers n care avem doar informaii despre aceast realitate material este, din pcate imposibil pentru prea muli dintre noi. Aa cum universul real poate fi reprezentat sub forma unor informaii digitale i produsul imaginaiei noastre poate fi reprezentat, la fel de bine, sub aceast form. Coexistena n forma aceleai reprezentri a realului i a imaginarului este fr indoial suportul universului virtual. Acest nou univers, generat de saltul tehnologic de la sfritul secolului XX este n plin expansiune i probabil muli dintre noi se vor muta aici ct de curnd. n universul real, dac frecvena unui semnal este audibil, atunci el poate fi doar auzit, dar nu poate fi vzut atta timp ct creierul nostru nu sufer de o afeciune ce ine de domeniul parapsihologiei. Pentru a fi vzut, el trebuie s fie ntr-un domeniu de frecvene numit spectru

110

Perioada i Frecvena unui Semnal Extern

vizibil. Aa c, pentru a vedea ceea ce ar trebui doar s auzim, vom apela la suportul tehnologic oferit de calculatorul personal. Nu trebuie s uitm nici un moment c suntem ntr-un univers virtual, iar aici, n sfrit, nu mai avem nici o grani ntre realitate i imaginaie. Pentru a putea scrie programul prin care s vedem sunetul, trebuie mai nti s nvm cte ceva despre capabilitiile grafice ale calculatorului personal IBM PC. Dac n programele de pna acum am utilizat numai modul text al ecranului reinem c pentru a putea desena pe ecran acesta va trebui controlat la nivel de pixel (punct pe ecran). Modurile grafice spre deosebire de modurile text ne permit s desenm puncte pe ecran, i astfel s construim pe ecran imagini orict de complexe. Numrul de pixeli pe care-i putem controla, pe ecran, depinde de modul de lucru ales. Pentru a putea alege un mod din ce n ce mai performant, avem nevoie de o placa video i un monitor din ce n ce mai performante. Cu alte cuvinte, cu ct modul grafic ales are o rezoluie mai mare (numr de pixeli raportat la numrul de culori pe pixel) cu att avem nevoie de mai mult memorie diponibil pe placa video (numit memorie video nu numai din motive legate de destinaie ct mai ales pentru a justifica performanele electrice ale acesteia). Deoarece placa video din calculatoarele personale compatibile IBM PC a avut fr ndoial cea mai tumultoas istorie i este nc o component n plin evoluie, nu vom insista asupra modurilor de lucru ale ecranului aa-zis "istorice". Sistemele moderne de operare utilizeaz numai modul grafic de nalt rezoluie al plcilor video. La rndul lor, acestea (placile video) ncorporeaz procesoare specializate n prelucrarea avansat a imaginilor. Scopul programelor din acest capitol este numai acela de a ilustra capabilitiile grafice ale calculatoarelor i relaia dintre imaginea vizualizat pe ecran i parametri fizici ai unui semnal extern. Fiecare pixel de pe ecran are o coordonat de rnd i una de coloan. Dac apelm la seviciile BIOS, lucrul n mod grafic nu ridic mari dificulti. Astfel, vom invoca serviciile de ecran din componenta BIOS (INT 10) pentru stabilirea modului de lucru a ecranului respectiv pentru a desena un punct pe ecran. Dac cu ajutorul programului precedent am auzit semnalul extern produs de generatorul de semnal dreptunghiular n continuare apelnd la facilitiile utilitarului DEBUG vom realiza un program prin intermediul caruia s vizualizm pe ecran acest semnal.
-a100 1371:0100 1371:0102 1371:0104 1371:0107 1371:0109 1371:010B 1371:010F jmp 126 mov dx,bx mov bx,0000 mov ah,0c int 10 cmp cx,027f jz 114 ;salt la adresa de start a programului ;deseneaz un punct pe ecran, mod grafic

;numr maxim de coloane

Microprocesoare i Microcontrolere
1371:0111 inc cx 1371:0112 jmp 123 1371:0114 mov cx,0000 1371:0117 cmp dx,01df 1371:011B jz 120 1371:011D inc dx 1371:011E jmp 123 1371:0120 mov dx,0000 1371:0123 mov bx,dx 1371:0125 ret 1371:0126 mov dx,378 1371:0129 mov al,80 1371:012B out dx,al 1371:012C mov bx,0000 1371:012F mov cx,0000 1371:0132 mov al,12 1371:0134 mov ah,00 1371:0136 int 10 1371:0138 mov dx,379 1371:013B in al,dx 1371:013C and al,40 1371:013E ror al,1 1371:0140 ror al,1 1371:0142 ror al,1 1371:0144 ror al,1 1371:0146 ror al,1 1371:0148 ror al,1 1371:014A call 0102 1371:014D mov ah,01 1371:014F int 16 1371:0151 jz 0138 1371:0153 mov ah,00 1371:0155 mov al,02 1371:0157 int 10 1393:0159 mov dx,378 1393:015C mov al,00 1393:015E out dx,al 1393:015F mov ax,4c00 1393:0162 int 21 1393:0164 -nppvdos.com -rcx CX 0000 :64 -w Writing 00064 bytes -

111

;numr maxim de linii

;alimentm generatorul de semnal

;fixm poziia iniial ecran mod grafic ;fixm mod grafic - 12h

;citim stare semnal extern, ACK ;reinem numai informaia util ;o poziionm pentru serviciul video

;deseneaz un punct pe ecran ;testm keyboard ;daca nu este tasta apasat ;altfel, trecem n mod text

;oprim generatorul de semnal

;invocm ieire n DOS

Rularea programului precedent va determina comutarea ecranului n modul grafic prin invocarea INT 10 urmat de desenarea pe ecran a unor imagini a cror form este greu de interpretat. Forma acestor imagini este puternic influenat de frecvena semnalului dreptunghiular (poteniometrul de 100k). Pentru unele

112

Perioada i Frecvena unui Semnal Extern

frecvene se pot obine imagini relativ stabile de forma celor prezentate n figura 6.3. Dac facem o paralel cu imaginile TV am putea spune c avem imagini nesincronizate. Lucrul acesta este pe deplin adevrat deoarece nu am stabilit n programul precedent nici o condiie/relaie ntre semnalul extern i imaginea desenat pe ecran. Un alt neajuns al programului ar fi pierderea informaiei iniiale, sunetul. Aa c, se prefigureaz dou direcii de aciune: pe de o parte recuperarea informaiei audio i pe de alt parte obinerea unor imagini stabile pe ecran, indiferent de frecvena semnalului dreptunghiular generat de modulul de extensie. Chiar cu neajunsurile menionate anterior programele precedente sunt un mare pas nainte spre stadiul de novice n domeniul embedded system. Acum suntem convini c un semnal extern poate ajunge sub form de "informaie despre el" n calculator, iar pe baza acestei informaii acesta poate fi recreat (sub form de sunet) sau poate fi creat o imagine cu o form dependent de parametrii unui semnal extern.

Figura 6.3. Exemplu de imaginea obinut pe ecran prin rularea programului ppvdos.com.

Dac nu cumva suntem "academicieni ocupai cu pontajul oamenilor de tiin", putem realiza un program care s execute simultan cele dou task-uri (sunet

Microprocesoare i Microcontrolere

113

i imagine) din programele precedente. Aa c, apelnd la utilitarul DEBUG vom putea realiza urmtorul program:
-a100 1371:0100 1371:0102 1371:0104 1371:0107 1371:0109 1371:010B 1371:010F 1371:0111 1371:0112 1371:0114 1371:0117 1371:011B 1371:011D 1371:011E 1371:0120 1371:0123 1371:0125 1371:0126 1371:0129 1371:012B 1371:012C 1371:012F 1371:0132 1371:0134 1371:0136 1371:0138 1371:013B 1371:013C 1371:013E 1371:0140 1371:0142 1371:0144 1371:0146 1371:0148 1393:0149 1393:014A 1393:014B 1393:014D 1393:014E 1393:0150 1393:0152 1393:0154 1393:0155 1393:0156 1393:0158 1393:015B 1393:015D 1393:015F 1393:0161 jmp 126 mov dx,bx mov bx,0000 mov ah,0c int 10 cmp cx,027f jz 114 inc cx jmp 123 mov cx,0000 cmp dx,01df jz 120 inc dx jmp 123 mov dx,0000 mov bx,dx ret mov dx,378 mov al,80 out dx,al mov bx,0000 mov cx,0000 mov al,12 mov ah,00 int 10 mov dx,379 in al,dx and al,40 ror al,1 ror al,1 ror al,1 ror al,1 ror al,1 push bx push ax push ax in al,61 pop bx and al,fd or al,bl out 61,al pop ax pop bx ror al,1 call 0102 mov ah,01 int 16 jz 0138 mov ah,00

114
1393:0163 mov 1393:0165 int 1393:0167 mov 1393:016A mov 1393:016C out 1393:016D mov 1393:0170 int 1393:0172 -nppavdos.com -rcx CX 0000 :72 -w Writing 00072 al,02 10 dx,0378 al,00 dx,al ax,4c00 21

Perioada i Frecvena unui Semnal Extern

bytes

Dac ne bazm pe experiena noastr n acest domeniu, acumulat pn n prezent, i comentariile ce nsoesc programele precedente, nelegerea acestora nu ar trebui s fie n acest stadiu o problem pentru noi. Acum suntem mai aproape ca niciodat de stadiul de novice n domeniul embedded system. A fost uor s scriem un program care s produc simultan sunet i imagine, numai c imaginea n continuare depinde n mod aleatoriu de frecvena semnalului extern. Pentru a elimina acest neajuns este necesar realizarea unui program care s produc pe ecran o imagine sincron. Dou informaii sunt bine localizate temporal n evoluia semnalului dreptunghiular. Acestea sunt tranziia din "0" logic n "1" logic a semnalului respectiv tranziia din "1" logic n "0" logic. Deoarece n cazul tranziiei din "0" logic n "1" logic avem de-a face la ieirea generatorului de semnal dreptungiular cu o trecere de la o tensiune mic la una mare vom spune n continuare c aceast trecere este frontul pozitiv al semnalului dreptunghiular. Prin analogie pentru tranziia invers avem frontul negativ al semnalului dreptunghiular. Aa c, imaginea de pe ecran poate fi sincron cu frontul pozitiv sau negativ al semnalului extern. n acest moment ideea prinde contur i se poate spune c desenarea fiecrei linii pe ecran trebuie nceput simultan (sincron) cu un front al semnalului extern. Acest lucru implic existena n corpul programului a unei proceduri de testare a uneia din condiiile menionate. Aceasta procedur o vom numi n continuare procedur de sincronizare. Desenarea fiecrei linii din imagine este precedat de invocarea procedurii de sincronizare. n continuare vom apela la serviciile utilitarului DEBUG pentru a realiza urmtorul program:
-a 1393:0100 1393:0102 1393:0104 1393:0107 1393:0109 jmp mov mov mov int 126 dx,bx bx,0000 ah,0c 10

Microprocesoare i Microcontrolere
1393:010B 1393:010F 1393:0111 1393:0112 1393:0114 1393:0117 1393:011B 1393:011D 1393:011E 1393:0120 1393:0123 1393:0125 1393:0126 1393:0129 1393:012B 1393:012C 1393:012F 1393:0132 1393:0134 1393:0136 1393:0138 1393:013B 1393:013C 1393:013E 1393:0140 1393:0141 1393:0143 1393:0145 1393:0147 1393:0149 1393:014B 1393:014E 1393:014F 1393:0151 1393:0153 1393:0155 1393:0157 1393:0159 1393:015B 1393:015D 1393:0160 1393:0164 1393:0166 1393:0168 1393:016A 1393:016C 1393:016F 1393:0171 1393:0174 1393:0176 1393:0177 1393:017A 1393:017C cmp cx,027f jz 114 inc cx jmp 123 mov cx,0000 cmp dx,01df jz 120 inc dx jmp 123 mov dx,0000 mov bx,dx ret mov dx,378 mov al,80 out dx,al mov bx,0000 mov cx,0000 mov al,12 mov ah,00 int 10 mov dx,379 in al,dx and al,40 mov ah,al in al,dx and al,40 cmp al,ah jz 13b cmp al,00 jz 13b mov dx,379 in al,dx and al,40 ror al,1 ror al,1 ror al,1 ror al,1 ror al,1 ror al,1 call 102 cmp cx,027f jnz 14b mov ah,01 int 16 jz 138 mov ax,0002 int 10 mov dx,378 mov al,00 out dx,al mov ax,4c00 int 21

115

;procedura de sincronizare

;dac nu este al diferit de ah > salt ;dac este al = 0 > salt

116
-nppvsn.com -rcx CX 0000 :7c -w Writing 0007C bytes -

Perioada i Frecvena unui Semnal Extern

De la linia de comand lansm n execuie programul precedent. Ecranul trece n mod grafic, iar pe ecran trebuie s obinem o imagine sincron indiferent de frecvena semnalului extern. O astfel de imagine este prezentat n figura 6.4 i dup cum uor se poate constata, fiecare linie din imaginea de pe ecran ncepe imediat dup frontul negativ.

Figura 6.4. Exemplu de imaginea obinut pe ecran prin rularea programului ppvsn.com.

Lansm utilitarul DEBUG i ncrcm programul recent realizat. Fr a rescrie programul, cu ajutorul urmtoarelor comenzi realizm o nou versiune a programului precedent care va sincroniza imaginea de pe ecran pe frontul pozitiv al semnalului extern.

Microprocesoare i Microcontrolere

117

-a149 1393:0149 jnz 13b 1393:014B -nppvsp.com -rcx CX 0000 :7c -w Writing 0007C bytes -

;dac nu este al = 0 > salt

Dac lansm n execuie acest nou program, vom obine pe ecran o imagine asemntoare cu ceea din figura 6.5. Desigur forma imaginii depinde de frecvena semnalului extern, dar pentru orice frecven imaginea obinut va fi sincron cu frontul pozitiv al acestuia.

Figura 6.5. Exemplu de imaginea obinut pe ecran prin rularea programului ppvsp.com.

Cu ajutorul serviciilor utilitarului DEBUG realizm n continuare un nou program n care imaginea obinut va fi sincron pentru un numr de linii cu frontul pozitiv al semnalului extern i pentru un numr de linii cu frontul negativ. Printr-o

118

Perioada i Frecvena unui Semnal Extern

bun gestionare a ecranului se poate obine o imagine gen "tabl de ah" (la o frecven dat a semnalului extern) de forma celei din figura 6.6.
-a 1393:0100 1393:0102 1393:0104 1393:0107 1393:0109 1393:010B 1393:010F 1393:0111 1393:0112 1393:0114 1393:0117 1393:011B 1393:011D 1393:011E 1393:0120 1393:0123 1393:0125 1393:0126 1393:0129 1393:012A 1393:012C 1393:012E 1393:012F 1393:0131 1393:0133 1393:0135 1393:0137 1393:0139 1393:013A 1393:013D 1393:013E 1393:0140 1393:0142 1393:0143 1393:0145 1393:0147 1393:0149 1393:014B 1393:014D 1393:014E 1393:0151 1393:0154 1393:0156 1393:0158 1393:015A 1393:015D 1393:015F 1393:0160 1393:0163 JMP MOV MOV MOV INT CMP JZ INC JMP MOV CMP JZ INC JMP MOV MOV RET MOV IN AND MOV IN AND CMP JZ CMP JNZ RET MOV IN AND MOV IN AND CMP JZ CMP JZ RET MOV MOV MOV MOV INT MOV MOV OUT MOV IN 014E DX,BX BX,0000 AH,0C 10 CX,027F 0114 CX 0123 CX,0000 DX,01DF 0120 DX 0123 DX,0000 BX,DX DX,0379 AL,DX AL,40 AH,AL AL,DX AL,40 AL,AH 0129 AL,00 0129 DX,0379 AL,DX AL,40 AH,AL AL,DX AL,40 AL,AH 013D AL,00 013D BX,0000 CX,0000 AL,12 AH,00 10 DX,0378 AL,80 DX,AL DX,0379 AL,DX

Microprocesoare i Microcontrolere
1393:0164 1393:0166 1393:0168 1393:016A 1393:016C 1393:016E 1393:0170 1393:0172 1393:0175 1393:0179 1393:017B 1393:017D 1393:017F 1393:0181 1393:0183 1393:0186 1393:0188 1393:018B 1393:018D 1393:0190 1393:0192 1393:0195 1393:0197 1393:019B 1393:019D 1393:01A0 1393:01A2 1393:01A6 1393:01A8 1393:01AB 1393:01AD 1393:01B1 1393:01B3 1393:01B6 1393:01B8 1393:01BC 1393:01BE 1393:01C1 1393:01C3 1393:01C7 1393:01C9 1393:01CC 1393:01CE 1393:01D2 1393:01D4 1393:01D7 1393:01D9 1393:01DB 1393:01DE 1393:01E0 1393:01E3 1393:01E5 1393:01E6 AND ROR ROR ROR ROR ROR ROR CALL CMP JNZ MOV INT JZ JMP CMP JGE CALL JMP CMP JGE CALL JMP CMP JGE CALL JMP CMP JGE CALL JMP CMP JGE CALL JMP CMP JGE CALL JMP CMP JGE CALL JMP CMP JGE CALL JMP JMP MOV INT MOV MOV OUT MOV AL,40 AL,1 AL,1 AL,1 AL,1 AL,1 AL,1 0102 CX,027F 0160 AH,01 16 0183 01DB DX,003C 018D 0126 0160 DX,0078 0197 013A 0160 DX,00B4 01A2 0126 0160 DX,00F0 01AD 013A 0160 DX,012C 01B8 0126 0160 DX,0168 01C3 013A 0160 DX,01A4 01CE 0126 0160 DX,01DF 01D9 013A 0160 0188 AX,0002 10 DX,0378 AL,00 DX,AL AX,4C00

119

120
1393:01E9 INT 21 1393:01EB -nppvspn.com -rcx CX 0000 :eb -w Writing 000EB bytes -

Perioada i Frecvena unui Semnal Extern

Programul precedent dei nu este comentat este uor de neles deoarece practic nu are elemente noi n raport cu celelalte programe prezentate pn acum n aceast capitol. Privind cu atenie imaginea din figura 6.6 constatm c generatorul de semnal dreptunghiular este departe de a fi ideal. Factorul de umplere nu este de 50% adic timpul ct semnalul are nivel logic "0" este mai lung dect timpul ct semnalul are nivel "1" logic. Aceasta este o particularitate a generatorului de semnal dreptunghiular i se datoreaz faptului c a fost proiectat n ideea de a fi ct mai simplu i fr alimentare extern.

Figura 6.6. Exemplu de imaginea obinut pe ecran prin rularea programului ppvspn.com

Microprocesoare i Microcontrolere

121

Un bun exemplu de antrenament ar fi realizarea unui program care s elimine prin software acest neajuns al generatorului de semnal dreptunghiular. Adic, ar trebui ca funcie de frecvena semnalului extern programul s fac o corecie n timp real al factorului de umplere al semnalului (se poate i mai simplu), dar care este frecvena semnalului extern i cum o putem afla? Cu ajutorul unui algoritm clasic de msurare a frecvenei (numrul de perioade contorizate ntr-o fereastr de timp egal cu 1 secund) putem afla frecvena semnalului aplicat la intrarea D6 (ACK) a portului de adres 0379h. n acest moment suntem n faa celei mai grele sarcini din cadrul acestui capitol. Trebuie s ne imaginm un program care trebuie s fac simultan dou lucruri. Programul trebuie s incrementeze o valoare, iniial egal cu zero, la fiecare front negativ al semnalului (ntre dou fronturi de acelai tip avem o perioad a semnalului extern) i n acelai timp s contorizeze trecerea timpului pentru a implementa o fereastr de numrare a perioadelor semnalului extern egal cu o secund. Singura posibilitate const n realizarea a dou task-uri care s ruleze simultan i s fac schimb de informaii ntre ele. Task-ul care contorizeaz trecerea timpului va fi activat la fiecare 54 ms de ntreruperea de ceas (tick), aa c vom contoriza 18 astfel de ntreruperi pentru o secund (0.972 s, adic o eroare acceptabil pentru msurarea frecvenei de 2,8%). Vom spune c acest task ruleaz n background activat de ntreruperea de ceas a calculatorului. Spre deosebire de acesta, un alt task va rula n foreground i va contoriza numrul de perioade al semnalului extern evalund totodat i informaia rezultat prin rularea task-ului din background. Cu ct task-ul din background va fi rulat ntr-o fereastr de timp mai mic, cu att performanele electrice ale frecvenmetrului implementat prin software vor fi mai bune (frecvena maxim ce poate fi msurat va fi mai mare). Aa c, este nevoie ca task-ul de contorizare a timpului s fie ct mai scurt posibil iar transferul de informaie (informaia legat de trecerea timpului) s fie ct mai simplu i s nu consume inutil din resursele de timp ale microprocesorului. Pentru a realiza acest deziderat vom sacrifica un registru al microprocesorului numai pentru acest scop. De asemenea, pentru a nu complica inutil programul, frecvena semnalului va fi afiat n hexazecimal. Plecnd de la informaiile precedente, cu ajutorul utilitarului DEBUG vom realiza urmtorul program.
-a 1371:0100 1371:0102 1371:0103 1371:0105 1371:0107 1371:0109 1371:010A jmp 13d push ax dec bl mov al,20 out 20,al pop ax iret ;salt la adresa de start ;noul serviciu de ceas, ~ 1s ;decrementm timp ;secvena EOI

;return din intrerupere

122
1371:010B 1371:010E 1371:0111 1371:0113 1371:0116 1371:0118 1371:011A 1371:011B 1393:011D 1393:011F 1393:0121 1393:0123 1393:0124 1393:0128 1393:012A 1393:012C 1371:012E 1371:0130 1371:0132 1371:0136 1371:0139 1371:013A 1371:013C 1371:013D 1371:0140 1371:0142 1371:0143 1371:0145 1371:0146 1371:0149 1371:014B 1371:014C 1371:014F 1371:0150 1371:0151 1371:0154 1371:0155 1371:0157 1371:0158 1371:0159 1371:015C 1371:015F 1371:0160 1371:0163 1371:0165 1371:0167 1371:016A 1371:016C 1371:016F 1371:0172 1371:0173 1371:0174 1371:0175 add dl,30 cmp dl,3a jl 116 add dl,07 mov ah,02 int 21 ret shl dx,1 shl dx,1 shl dx,1 shl dx,1 push dx and dx,f000 mov dl,dh shr dx,1 shr dx,1 shr dx,1 shr dx,1 and dx,000f call 10b pop dx loopnz 11b ret mov dx,378 mov al,80 out dx,al in al,21 push ax mov ax,0000 mov es,ax es: mov ax,[0020] push ax es: mov ax,[0022] push ax mov ax,cs cli es: mov [0022],ax mov ax,0102 es: mov [0020],ax mov al,fe out 21,al mov bx,0012 mov ah,40 mov cx,0000 mov dx,379 sti hlt in al,dx cmp bl,bh

Perioada i Frecvena unui Semnal Extern


;subrutine de conversie, tiprire

;alimentm generatorul de semnal

;capturm stare controler, 8259 ;reimen vector de ceas vechi

;modificm vector de ceas

;lsm activ numai ntreruperea de ceas ;fixm lungimea ferestrei de timp ;iniializm contor perioade ;sicronizare cu intrerupere ceas

;test dac a trecut timpul

Microprocesoare i Microcontrolere
1371:0177 jz 189 1371:0179 test al,ah 1371:017B jnz 174 1371:017D in al,dx 1371:017E cmp bl,bh 1371:0180 jz 189 1371:0182 test al,ah 1371:0184 jz 17d 1371:0186 inc cx 1371:0187 jmp 174 1371:0189 cli 1371:018A pop ax 1371:018B es: 1371:018C mov [0022],ax 1371:018F pop ax 1371:0190 es: 1371:0191 mov [0020],ax 1371:0194 pop ax 1371:0195 out 21,al 1371:0197 sti 1371:0198 push cx 1371:0199 mov dl,20 1371:019B call 116 1371:019E mov cx,0004 1371:01A1 pop dx 1371:01A2 call 123 1371:01A5 mov dl,0d 1371:01A7 call 116 1371:01AA mov ah,01 1371:01AC int 16 1371:01AE jz 1bb 1371:01B0 mov dx,378 1371:01B3 mov al,00 1371:01B5 out dx,al 1371:01B6 mov ax,4c00 1371:01B9 int 21 1371:01BB jmp 13d 1371:01BD -nppfdos.com -rcx CX 0000 :bd -w Writing 000BD bytes -

123

;test front

;test dac a trecut timpul ;test front ;incrmentm contor perioade semnal ;dac nu a trecut timpul relum ;refacem stare iniiala vector ceas

;refacem stare iniial controler, 8259 ;ntreruperi active ;tiprim rezultatul

;testm keyboard

;oprim generatorul de semnal

;invocm ieire DOS

Structura programului precedent o putem considera clasic. ncepem cu o instruciune de salt (JMP) peste subrutine la adresa de start a programului. Buna funcionare a programului este asigurat de redirectarea ntreruperii de ceas, n acest exemplu la adresa 1371:0102, unde se afl noul serviciu al ntreruperii de ceas (pn la instruciunea IRET). Deoarece odat cu redirectarea acestei ntreruperi toate

124

Perioada i Frecvena unui Semnal Extern

celelalte ntreruperi au fost mascate prin programarea corespunztoare a circuitului 8259 (a fost prezentat pe larg n capitolul 5), singura ntrerupere activ pe parcursul unei secvene de msurare este ntreruperea de ceas. Dup cum se poate constata, noua subrutin care deservete ntreruperea de ceas nu face altceva dect s decrementeze registrul partajat (sacrificat) BL i s comunice circuitului 8259 c ntreruperea a fost deservit (EOI, End Of Intereupt). Desigur, pe perioada msurrii frecvenei semnalului extern, ceasul de sistem nu contorizeaz trecerea timpului, aa c, odat cu fiecare msurtoare ceasul de sistem al calculatorului rmne n urm cu aproximativ o secund. n secvena de contorizare a perioadelor semnalului extern din task-ul care ruleaz n foreground este verificat i trecerea timpului prin evaluarea valorii curente din registrul partajat BL. n acest fel, cele dou task-uri comunic ntre ele printr-un protocol simplu i extrem de eficient din prisma performanelor electrice ale instrumentului implementat prin software (instrument virtual). Afiarea frecvenei se face n hexazecimal, pentru a nu complica inutil programul. Pentru un novice n domeniul embedded system acest lucru nu mai trebuie s fie un impediment. n continuare, pentru a evalua performanele calculatorului pe care ne antrenm, lansm n execuie aplicaia precedent i fixm din poteniometrul de 100k frecvena semnalului extern egal cu 1000 Hz, adic 3E8h n hexazecimal. Cu ajutorul programelor din acest capitol putem s auzim, respectiv vedem, semnalul extern. Vom lansa n final n execuie unul din programele de vizualizare a semnalului cu sincronizare pe frontul pozitiv sau negativ i vom stabili numrul de perioade ale semnalului extern vizibile pe ecran atunci cnd frecvena acestuia este de 1000 Hz. tiind c pe orizontal imaginea are 640 de pixeli este uor s calculm de cte ori pe secund sistemul, prin rularea programului, poate s citeasc o informaie din portul paralel i s o afieze n mod grafic pe ecran. Informaia pe care o obinem prin algoritmul prezentat anterior ne va da o imagine clar despre ce ar putea face un calculator personal de tip IBM PC, numai prin proceduri software, n domeniul achiziiei, respectiv prelucrrii de semnal. n funcie de aplicaia concret pe care o avem n vedere, n urma constatrilor anterioare vom fi entuziasmai sau dezamgii. Asta este, n practic niciodat un calculator nu va fi att de rapid nct s putem rezolva prin software orice aplicaie. Aceast constatare a determinat gsirea altor soluii hardware/software care au transformat n timp domeniul embedded system ntr-o jungl, n care, dup cum putem constata, cu greu se poate ptrunde. Au aprut microprocesoare cu arhitecturi noi, circuite programabile extrem de complexe i specializate i nu n ultimul rnd, sisteme de operare pentru aplicaiile n timp real. Acest lucru a generat n timp subdomenii specializate ale domeniului embedded

Microprocesoare i Microcontrolere

125

system. De altfel, pe un asemenea subdomeniu (calculatoarele personale IBM PC) noi am atins stadiul de novice. n urmtoarele trei capitole vom atinge stadiul de "novice bine informat" n domeniul embedded system. Dac programele de pn acum sunt clare, s trecem mai departe, partea frumoas abia de acum se arat. Dar dac nu am rmas cu mare lucru din munca de pn acum, ar fi mai bine, s ne gndim serios la o alt meserie. Fiecare om nu va putea face performan dect ntr-un domeniu dat, acesta ns, din pcate, nu de puine ori trebuie cutat toat viaa. Preocuparea de baz n domeniul embedded system este aceea de a ngloba "inteligena microprocesoarelor" n tot ce a fost realizat tehnologic pn n prezent i n tot ce se va realiza n viitor. Acest adaos "de astfel de inteligen" aduce mari beneficii n performanele aplicaiilor n preul i fiabilitatea acestora, ct i facilitii legate de uurina folosirii acestor aplicaii. Toate acestea vor marca profund viaa de zi cu zi a oamenilor cel puin n primul secol al mileniului trei. n raport cu noile tehnologii fiecare dintre noi poate fi cu uurin spectator, utilizator, sau creator. Este cu adevrat o piatr de ncercare s devenim din utilizatori creatori de noi tehnologii sau cel puin creatori de noi aplicaii ale tehnologiilor actuale. Nu vom tii niciodat cu siguran dac suntem creatori veritabili n acest domeniu, dar avem un indiciu c suntem pe drumul cel bun, statul de plat. Este greu de neles cum se pot obine foloase materiale n spaiul real n urma unor activiti prestate n spaiul virtual. Probabil viitoarele realizri din domeniul ingineriei genetice (adic orice nou nscut va tii totul despre domeniul embedded system tot aa cum tie acum s respire) vor pune n pericol aceast afacere a zilelor noastre. Unul din subdomeniile embedded system-ului, aflat n plin maturitate i pe deopotriv ascensiune, este cel al sistemelor cu microcontroler. Acestea nu sunt nimic altceva dect nite calculatoare mai mult sau mai puin specializate, realizate ntr-un singur chip (on-chip computer). S le vedem la lucru.

126

Perioada i Frecvena unui Semnal Extern

Microprocesoare i Microcontrolere

127

7. Microcontrolerul 68HC11. PcBug

Nu pentru orice aplicaie se justific utilizarea unui microprocesor puternic de tipul celor studiate pn n prezent. Pe de alt, parte apelarea la un calculator personal n orice aplicaie ridic nejustficat preul de cost al acesteia sau face chiar imposibil (datorit costului) utilizarea tehnologiei calculatoarelor personale IBM PC. Nevoia fireasc de a ridica performanele produselor prin aportul adus de tehnologia microprocesoarelor a determinat apariia i dezvoltarea aproape simultan a unor calculatoare "on-chip" (microprocesorul, memoria i periferia pe o singur pastil de siliciu). Acestea s-au constituit ntr-o clas aparte cunoscut sub denumirea de microcontrolere. Desigur, acestea (microcontrolerele) sunt de regul suportul fizic al aplicaiilor n domeniul embedded system. Chiar dac aa stau lucrurile, n realitate noi nu am nceput cu acestea, din dou motive. Un prim motiv este nevoia unei culturi minime n domeniul microprocesoarelor i respectiv a calculatorului personal IBM PC pentru a putea aborda miezul tare al domeniului embedded system cu succes. Timpul n care pot fi nvate unele elemente de baz ale domeniului prin intermediul calculatorului personal IBM PC poate fi extrem de scurt. Aa c un al doilea scop este de ordin didactic. Desigur, n acelai timp am reuit s clarificm unele probleme legate de arhitectura i programarea calculatorului personal IBM PC. Pe baza cunotiinelor acumulate pn acum se pot realiza multe aplicaii de achiziie de date i control. Modul de abordare al problemelor de achiziie de date i control prezentat pn acum n aceast carte era caracteristic anilor '80 eventual '90. Nevoia de cretere a performanelor acestor aplicaii la un pre de cost din ce n ce mai mic a fost posibil prin apariia unor microprocesoare, respectiv microcontrolere, specializate. Astfel, pentru fiecare clas de aplicaii, la ora actual o serie de firme ofer suport software bazat pe un hardware specializat. Aa c, de cele mai multe ori este lipsit de argument tiinific i/sau economic particularizarea unui calclulator personal IBM PC numai pentru o anumit aplicaie. De altfel, evoluia sistemelor de operare, dup cum am putut constata, a dus la o situaie din ce n ce mai restrictiv cu abordarea clasic a problemelor de achiziie de date i control. Capacitatea unui hardware-software specializat de a prelucra local task-urile aplicaiei dublat de capacitatea acestuia de a comunica prin intermediul unui canal standard degreveaz calculatorul personal IBM PC de interacia cu o periferie primitiv care, de regul, tinde s monopolizeze timpul microprocesorului n favoarea ei. n aceast situaie calculatorul personal IBM PC poate superviza mai

128

Microcontrolerul 68HC11. PcBug

multe aplicaii n acelai timp, iar task-urile acestora vor fi rezolvate simultan i/sau n timp real de ctre mai multe centre de prelucrare-decizie. ntr-o asemenea concepie de procesare distribuit a datelor este uor s ne imaginm, de exemplu, aplicaii de achiziie de date i control conduse prin Internet. Fr a intra n disputa dintre firmele productoare i fanii acestora, microcontrolerul 68HC11 de la firma Motorola s-a dovedit la data apariiei un produs extrem de flexibil i puternic la nivelul microcontrolelelor de 8/16 bii. Combinarea n acelai chip a unei uniti centrale, bazate pe tradiionalul microprocesor M6800 de la firma Motorola, a unor circuite de memorie performante (EEPROM), ct i a unei periferii extrem de diversificate i flexibile a dus fr ndoial la succesul acestui proiect. Pentru nceput, vom ncerca s ne facem o imagine general despre acest microcontroler. Studiul lui va trebui ns aprofundat n particular pentru a putea pune n oper aplicaii reale cu o alt utilitate dect cea didactic, demonstrativ.

Figura 7.1. Diagrama pinilor la microcontrolerul 68HC11 (PLCC).

Microprocesoare i Microcontrolere

129

Microcontrolerul 68HC11 (figura 7.1) este realizat n tehnologia HCMOS (high-density complementary metal-oxide semiconductor) i conine n acelai chip o unitate avansat de procesare pe 8-bii, cel puin dou tipuri de memorie precum i o sofisticat periferie, toate acestea la o vitez nominal de bus de 2 Mhz. Microcontrolerul este static aa c el poate opera la frecvene joase practic pna la DC. Astfel, ntr-o aplicaie dat se pot face reduceri nsemnate de energie consumat de la sursa de alimentare. Principalele subsisteme ale microcontrolerului i modul de conectare al acestora la pini sunt prezentate n figura 7.2.

Figura 7.2. Diagrama bloc a microcontrolerului 68HC11.

Dup cum se poate constata din figura 7.2 n jurul unitii centrale de procesare (CPU - Central Processing Unit) microcontrolerul 68HC11 n versiunea 68HC11A8 are trei tipuri de memorie: EEPROM, RAM i ROM. O alt versiune a microcontrolerului 68HC811E2 are aceeai configuraie dar cu 2 Kbytes de memorie EEPROM i fr memorie ROM. n versiunea 68HC11A1 microcontrolerul nu are memorie ROM, iar n versiunea 68HC11A0 nu are memorie ROM i EEPROM. Acestea sunt cele mai uzuale versiuni ale acestui microcontroler, versiuni pe care de altfel le vom utiliza n continuare. Pe lng memoria intern microcontrolerul posed o puternic periferie specializat n

130

Microcontrolerul 68HC11. PcBug

comunicaie (SCI, SPI), timer, watchdog, convertor A/D, un subsistem pentru gestionarea ntreruperilor i porturi I/O de uz general (PORT B, PORT C). Dac pentru o aplicaie dat resursele microcontrolerului n mod "Single Chip" nu sunt suficiente (avem nevoie de mai mult memorie pentru program i/sau date ori mai multe porturi I/O) atunci porturile de uz general (PORT B, PORT C) pot fi transformate ntr-o magistral de adrese-date multiplexat prin trecerea microcontrolerului n mod "Expanded". Dup cum se poate vedea n figura 7.1 alegerea modului de lucru se face prin intermediul subsistemului "Mode Select". Modul de lucru al microcontrolerului este funcie de starea logic a doi pini (MODA, MODB) a cror semnificaie este prezentat n tabelul 7.1.
Tabelul 7.1.

Dup cum rezult din acest tabel microcontrolerul 68HC11 are dou moduri normale i dou moduri speciale. Pentru "Single Chip" avem un mod special (Special Bootstrap) care activeaz o memorie intern ROM ce conine un program pentru secvena de autoboot. Dup cum vom vedea, aceast facilitate extrem de important i unic n lumea microcontrolerelor face posibil dezvoltarea de aplicaii far a fi nevoie de un programator extern. Dintr-un mod special, se poate trece prin software la un mod normal. Pentru aceasta este nevoie s cunoatem semnificaia biilor registrului HPRIO (de la adresa $103C, prefixul "$" este o notaie tipic firmei Motorola pentru numere hexazecimale). Funcie de valorile biilor din registrul HPRIO prezentat n tabelul 7.2 microcontrolerul poate fi adaptat la o aplicaie dat.
Tabelul 7.2.

HPRIO:
SMOD - Special Mode Poate fi scris cu zero dar nu poate fi readus n unu din program

Microprocesoare i Microcontrolere
1 - Special mode 0 - Normal mode MDA - Mode A Select Poate fi scris numai dac SMOD este egal cu unu 1 - Normal Expanded sau Special test mode 0 - Normal Single Chip sau Special bootstrap mode

131

Acesta nu este singurul registru care asigur flexibilitate microcontrolerului 68HC11. O serie de ali regitri concur la aceast calitate unic a microcontrolerului. Prezentarea sumar a microcontrolerului urmat de cteva programe simple nu va putea scoate n eviden toate calitile acestei familii de microcontrolere. Utilizarea eficient a acestui microcontroler extrem de complex nu poate fi fcut fr un studiu al manualului de firm (Pink Book). Pentru nceput este nevoie s proiectm i realizm practic un sistem cu microcontrolerul 68HC11. Am optat pentru versiunea 68HC11A1 a microcontrolerului i o implementare n mod "Single-Chip". Aceast implementare conine pe lng 68HC11 i circuitul MAX232, care asigur compatibilitatea electric ntre interfaa serial RS232 i microcontroler. Realizarea practic a unei astfel de aplicaii este prezentat n figura 7.3.

Figura 7.3. Realizarea practic a sistemului cu 68HC11 mod "Single-Chip".

132

Microcontrolerul 68HC11. PcBug

Fr a insista asupra prii de hardware, s vedem dac istoria din capitolele 1 - 6 se repet. Adic, s vedem dac cunotiinele acumulate pn acum ne ajut la abordarea acestei familii de microcontrolere. De data aceasta utilitarul minune se numete PCBUG i vom vedea n continuare n ce msur se aseamn sau nu cu utilitarul DEBUG. Desigur lucrurile nu stau chiar aa de simplu, n primul rnd utilitarul PCBUG nu mai este un program al sistemului de operare. Aa c, va trebui s-l ncrcm de pe un suport extern. Odat cu PCBUG va trebui s avem i alte programe (de exemplu un asamblor) toate disponibile ntr-o trus de scule (folder) pe care va trebui s-l creem i ntreinem singuri. O mare parte din programele de care avem nevoie le vom gasi gratuit pe Internet, unele dintre ele chiar pe unul din site-urile firmei Motorola. Lansarea n execuie a programului PCBUG trebuie precedat de realizarea unei conexiuni ntre sistemul cu 68HC11 i calculatorul gazd (IBM PC) precum i alimentarea respectiv resetrea acestuia. Pentru nceput, programul PCBUG va lansa un dialog de forma celui prezentat n continuare prin care informm programul despre particularitile sistemului extern.
PCbug11 Ver 3.42 - M68HC11 Monitor for PC Hosts (c) Motorola Ltd 1994 PCbug11 Command Line Compiler - press <Esc> to terminate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ Is the talker installed on your board? (Y/N) : N Do you wish to use the XIRQ interrupt? (Y/N) : N MCU boot talkers available ~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 68HC11A0/1/7/8 2 68HC11D0/3 4 68HC811E2 5 68HC11F1 7 68HC11J0/6 8 68HC11K0/4 10 68HC11ED0 11 68HC711E9 13 68HC711E20 14 68HC11EA9 16 68HC711G5 17 68HC711L6 19 68HC11KA4 20 68HC711KA4 22 68HC711M2 23 68HC11P2 Which device are you using? : 1 Do you wish to load a macro automatically? (Y/N) : N PC communications port : 1. COM1 2. COM2 Which communications port are you using? : port=2 Assume an 8MHz crystal in use (Y/N) : Y Command Line : PCBUG11 -A port=2 Press <Esc> to quit or any other key to run PCBUG11

3 68HC11E0/1/8/9 6 68HC11G0/5/7 9 68HC11L0/6 12 68HC11E20 15 68HC711EA9 18 68HC711K4 21 68HC11M2 24 68HC711P2

Microprocesoare i Microcontrolere

133

Prin apsarea oricrei taste cu excepia tastei "ESC" se va lansa n execuie programul. Dac parametrii fixai anterior sunt coreci i conexiunea dintre sisteme este bine realizat nu vor aprea nici un fel de probleme i vom ajunge n situaia prezentat n figura 7.4.

Figura 7.4. Utilitarul PCBUG lansat n execuie.

La fel ca i n cazul utilitarului DEBUG, prin comanda "help" putem obine toate comenzile acestui utilitar. Dat fiind complexitatea acestui sistem, att n ce privete organizarea memoriei interne, i mai ales datorit periferiei pe care o are microcontrolerul 68HC11, utilitarul PCBUG are o lista mare de comenzi astfel nct s fie uor de adaptat la orice situaie concret.
+-----------------------------------------------------------------------------+ MENU Use the host-computer keyboard to edit the PCbug11 command line. A recall buffer holds the last 16 commands entered. The following table lists the edit keys. left arrow - Moves cursor back one character right arrow - Moves cursor forward one character Home - Moves cursor to first character End - Moves cursor to last character delete left - Deletes to the left of the cursor Del - Deletes at the cursor position <CTRL> End - Deletes from cursor position to the end of line Ins - Inserts at cursor position (cursor changes to blocked

134

Microcontrolerul 68HC11. PcBug

cursor) +--- Viewing MENU ----- Line : 1 ---------------------------------------------+ +-----------------------------------------------------------------------------+ cursor) up arrow - Recalls previous commands, in reverse order down arrow - Recalls last command in recall buffer Esc - Clears command line or terminates most commands in progress The four lines above the command line serve as a trace of the last four commands. The fifth line above the command line shows breakpoints and error codes. Possible error codes are: 0 : No error 1 : VERF error 2 : MS or BF error 3 : Talker communication failure. +--- Viewing MENU ----- Line : 14 --------------------------------------------+ +-----------------------------------------------------------------------------+ 3 : Talker communication failure. For MS-DOS batch files, an error code can be checked via ERRORLEVEL after PCbug11 terminates. Monitor Commands The following is a summary of PCbug11 commands. ---------------------------------------------------------------------------- COMMAND DESCRIPTION ---------------------------------------------------------------------------- ASM addr [mne dir] Call symbolic macro line assembler, with +--- Viewing MENU ----- Line : 27 --------------------------------------------+ +-----------------------------------------------------------------------------+ ASM addr [mne dir] Call symbolic macro line assembler, with option to auto insert mnemonic or directive ---------------------------------------------------------------------------- BAUD [rate] Display or set serial baud rate BF addr1 [addr2] byte word Block fill memory with byte or word BL Display breakpoints BR [addr [macroname]] Display/Set break point [with optional macro execution] ---------------------------------------------------------------------------- CALL addr Execute the subroutine at addr CLRM Clear all command macros CLS Clear main window CONTROL Display or set CONTROL parameters CONTROL BASE BIN HEX DEC Change default number base +--- Viewing MENU ----- Line : 40 --------------------------------------------+ +-----------------------------------------------------------------------------+ CONTROL BASE BIN HEX DEC Change default number base CONTROL BIOS Access serial COM port through BIOS calls CONTROL COLOR Set PCbug11 display colors CONTROL COLOUR Set PCbug11 display colours CONTROL COM1 Use COM1 port CONTROL COM2 Use COM2 port

Microprocesoare i Microcontrolere
CONTROL EPROG address Change the EPROM register address CONTROL ERRMSG option Enable or disable display of error messages CONTROL HARDWARE Access COM port directly through hardware CONTROL LAST Toggle the last error message window on/off CONTROL LOG CLOSE Close the open command log file CONTROL LOG OFF Suspend logging to command log file CONTROL LOG ON Enable logging to the command log file CONTROL LOG OPEN Open the command log file +--- Viewing MENU ----- Line : 53 --------------------------------------------+ +-----------------------------------------------------------------------------+ CONTROL LOG OPEN Open the command log file CONTROL PPROG address Change the EEPROM register address CONTROL PROTECT Use the RTS to provide memory protection CONTROL RTS Control the RTS line directly CONTROL RTS ON OFF Set RTS line high or low CONTROL TIMEOUT [value] Display or set the value of serial COM timeout during input ---------------------------------------------------------------------------- DASM addr1 [addr2] Disassemble from addr1 [to addr2] DB startaddr [endaddr] Display MCU Memory DEBUG Reserved word DEFINE symbol value address Define a symbol DEFM macrnam TRACE AUTOSTART Define a command, trace or autostart macro DELM macrnam TRACE AUTOSTART Delete a command, trace or autostart macro +--- Viewing MENU ----- Line : 66 --------------------------------------------+ +-----------------------------------------------------------------------------+ DELM macrnam TRACE AUTOSTART Delete a command, trace or autostart macro DIR [mask] Display disk directory DOS [command] Shell to DOS or execute DOS command ---------------------------------------------------------------------------- EDITM macrnam Edit a macro EEPROM [startaddr [endaddr]] Display, clear, set EEPROM address range(s) EEPROM DELAY option Set EEPROM erase or write programming time EEPROM ERASE [option] Display or change EEPROM erase-before-write ENV Define Environment save options EPROM [startaddr [endaddr]] Display, clear, set EPROM address range(s) EPROM DELAY option Set EPROM erase or write programming time ---------------------------------------------------------------------------- FIND byte word addr1 addr2 Find all occurrences of byte or word between addr1 & addr2 +--- Viewing MENU ----- Line : 79 --------------------------------------------+ +-----------------------------------------------------------------------------+ between addr1 & addr2 FIND mnemonic addr1 addr2 Find all occurrences of mnemonic between addr1 & addr2 ---------------------------------------------------------------------------- G [addr] Start user code execution ---------------------------------------------------------------------------- HELP [command] Display help information HELP MCU [topic] Display help on specific MCU topic ---------------------------------------------------------------------------- KLE Kill last error message ---------------------------------------------------------------------------- LOADM [filename] [macroname] Load macro definitions from default or user file LOADS filename [loadaddr] Load S-record file into MCU memory +--- Viewing MENU ----- Line : 92 --------------------------------------------+

135

136

Microcontrolerul 68HC11. PcBug

+-----------------------------------------------------------------------------+ LOADS filename [loadaddr] Load S-record file into MCU memory LS symbol Display symbols LSTM [mname TRACE AUTOSTART] Display macro names or definitions ---------------------------------------------------------------------------- MD startaddr [endaddr] Display MCU memory MM addr Modify memory from addr MOVE addr1 addr2 addr3 Move MCU memory between addr1 & addr2 to addr3 MS addr byte word [byte word] Set MCU memory byte(s) or word(s) MSG [string] Display message in main window ---------------------------------------------------------------------------- NOBR [address] Remove all or specified breakpoints ---------------------------------------------------------------------------- PAUSE [ms] Wait for any key press or delay time +--- Viewing MENU ----- Line : 105 -------------------------------------------+ +-----------------------------------------------------------------------------+ PAUSE [ms] Wait for any key press or delay time PRINT Display PCbug11 version number PROTECT [startaddr [endaddr]] Display, clear or set write-protected address range(s) ---------------------------------------------------------------------------- QUIT [Y] Terminate PCbug11 session [without confirming] ---------------------------------------------------------------------------- RD [T] Display ot trace MCU registers RESET [addr] MCU Hardware Reset with Existing or new reset vector. RESTART [option] Restart PCbug11 with same or new option. RM Modify MCU registers in window RS register value Set value of MCU register +--- Viewing MENU ----- Line : 118 -------------------------------------------+ +-----------------------------------------------------------------------------+ RS register value Set value of MCU register ---------------------------------------------------------------------------- S Stop user code execution SHELL ["command" ;P] Shell to DOS or execute DOS command SAVEM [filename] Save macro definitions in default or user file ---------------------------------------------------------------------------- T [addr] Trace user code TERM [X1 Y1 X2 Y2] Simple windowed terminal emulator TYPE filename Display disk file in main window ---------------------------------------------------------------------------- UNDEF symbol Undefine a symbol ---------------------------------------------------------------------------- VER Display version number +--- Viewing MENU ----- Line : 131 -------------------------------------------+ +-----------------------------------------------------------------------------+ VER Display version number VERF ERASE addr1 [addr2] Verify that memory contains $FF VERF SET addr1 addr2 value Verify that memory contains the value VERF filename [memaddr] Verify S-record disk file against memory ---------------------------------------------------------------------------- WAIT [ms] Wait for ms ----------------------------------------------------------------------------

Microprocesoare i Microcontrolere
Special Key operations: ---------------------------------------------------------------------------- <CTRL> B Send break on COM channel <CTRL> P Toggle MCU memory write protect/RTS line <CTRL> R Attempt to re-synchronise talker ---------------------------------------------------------------------------- +--- Viewing MENU ----- Line : 144 -------------------------------------------+ +-----------------------------------------------------------------------------+ ---------------------------------------------------------------------------- EVS Compatible commands These commands operate in a similar manner to the command of the same name on the Motorola 68HC11 EVS systems. ASM, BF, BR, G, HELP, MD, MM, NOBR, RD, RM +--- Viewing MENU ----- Line : 157 -------------------------------------------+

137

Nici de aceast dat nu vom ncerca s le nvm pe de rost, acum tim cum le putem afla. Stadiul de novice n domeniul embedded system a fost atins n primele ase capitole din aceast carte, aa c de acum vom schia un eventual parcurs spre stadiul de "novice bine informat". Pentru a avea o mai mare productivitate este bine n acest stadiu s utilizm un asamblor exterm pe care trebuie s-l avem n cutia cu scule. Acesta (asamblorul) este gratuit. Aa c, noi vom utiliza n continuare pentru realizarea de programe un editor ASCII si asamblorul "asm11.exe". Cu ajutorul asamblorului vom obine fiierele n format hexazecimal de tip ".S19" care apoi cu ajutorul utilitarului PCBUG le vom ncrca n memoria EEPROM a microcontrolerului 68HC11 pentru a fi rulate de acesta. Pentru versiunea 68HC11A1 memoria EEPROM este paginat ncepnd cu adresa $B600 i are o lungime de 512 bytes. Aa c, n continuare, pentru a testa buna funcionare a sistemului cu 68HC11 (anexa B) vom realiza un fisier ASCII cu urmtorul coninut:
* test program for EEPROM, PD * Program "LEDPD3.ASM" * portd equ $08 ddrd equ $09 * org $b600 start lds #$ff ldx #$1000 bset ddrd,x$08

; org of EEprom

138
led ldaa eora staa ldd subd bne bra org fdb * end portd,x #$08 portd,x #$8000 #1 delai led $fffe start

Microcontrolerul 68HC11. PcBug

delay

; after Reset

Programul anterior nu face altceva dect s produc un semnal dreptunghiular de joas frecven la ieirea PD3 a microcontrolerului. Odat creat acest fiier l vom salva cu denumirea "LedPD3.asm" n acelai folder cu asamblorul (asm11.exe). Cu ajutorul asamblorului vom obine fiierul "LedPD3.s19" cu urmtorul coninut:
S11CB6008E00FFCE10001C0908A6088808A708CC800083000126FB20F0A7 S105FFFEB60047 S9030000FC

Pentru a ne convinge de buna funcionare a sistemului vom ncrca acest fiier n memoria EEPROM a lui 68HC11 i-l vom lansa n execuie.

Figura 7.5. ncrcarea unui program n memoria EEPROM.

Microprocesoare i Microcontrolere

139

Comenzile ce trebuie date n utilitarul PCBUG, respectiv rspunsul acestuia la aceste comenzi este prezentat n figura 7.5. Deoarece frecvena generat este foarte joas, funcionarea corect a programului anterior poate fi pus n eviden cu un simplu LED nseriat cu o resisten de 220 . n aceast etap, folosirea unui asamblor extern ne permite s realizm sursa n format ASCII a programelor. Aa c, de aceast dat programele noastre trebuie s fie comentate n aa fel nct odat cu programul s producem i documentaia aferent acestuia. Pentru a asigura o mai mare portabilitate a documentaiei aferente este bine nc de la nceput s facem toate comentariile n limba englez folosind pe ct se poate formulri consacrate.

Figura 7.5. Realizarea practic a modului LCD alfanumeric.

Chiar dac experiena precedent nu este deloc spectaculoas, la sfritul ei vom ti o mulime de comenzi utile i nu n ultimul rnd ne vom convinge de buna funcionare a sistemului. Este bine s reinem c, de fiecare dat, pe orice sistem, mult este pn reuim s aprindem un LED cum i cnd vrem noi. De aici ncolo, totul este munc de rutin. Pentru a ne convinge de acest lucru vom realiza n

140

Microcontrolerul 68HC11. PcBug

continuare un modul de afiare LCD (Liquid Cristal Display) de tip alfanumeric. Realizarea practic a acestui modul se poate vedea n figura 7.6. Modulul LCD prezentat anterior face parte din aceeai clas tehnologic cu 68HC11 i la rndul lui conine un microcontroler specializat HD44780. Acest microcontroler specializat comunic cu un alt sistem prin intermediul unor porturi paralele. Comunicarea se realizeaz printr-o magistral de date de 8/4 bii iar protocolul de comunicaie este asigurat printr-o magistral de control (E, R/W, RS, Enable control line, Read/Write control line, Register-Select control line). Pentru o bun nelegere a urmtorului program, va trebui s consultm fia tehnic (uor de gsit pe Internet) a modului LCD. Programul va trebui s in cont de tipul de transfer pe 8 sau 4 bii i de modul de organizare a ecranului LCD (numrul de rnduri respectiv numrul de caractere pe fiecare rnd). Pe de alt parte, modulul LCD are stocate n memoria intern de tip ROM mai multe pagini de caractere (acoper inclusiv aria asiatic) aa c, va trebui s selectm pagina de caractere care intenionm s le afim. De asemenea, putem defini, de regul, 8 caractere cu o grafic la alegere controlat la nivel de pixel. Programul prezentat n continuare este particularizat pentru situaia hardware prezentat n figura 7.6. i anume, sunt folosite numai cele 8 linii ale portului "PC". Astfel, sunt utilizate numai apte linii de I/O ale lui 68HC11 pentru a realiza un trasfer de informaie pe o magistral de date de numai 4 bii respectiv pentru a implementa protocolul de transfer prin magistrala de comenzi aferent (E, R/W, RS). Dac prin programul precedent am facut s plpie un LED, acum n acord cu primele noastre experiene n domeniul embedded sytem vom realiza un program care scrie pe ecranul modulului LCD " Hello World !...".
************************************* * PROGRAM "LCDHWE.ASM" * * * * * ************************************* ETX: EQU $04 REGS: EQU $1000 DDRC: EQU $07 PC: EQU $03

LOOPHW:

ORG LDS JSR JSR LDX JSR JMP

$B600 #$FF LCD4BIT LCDINIT #TEXTHW LCDTXT LOOPHW

Microprocesoare i Microcontrolere
TEXTHW: FCC FCB 'Hello World !...' ETX

141

************************************* * ROUTINE FOR NORMAL DIPLAY * * * * X-> pointer to strigt * * end of string $04, * * line control $0A * * if present change the line * * * * Reg aff: X,CCR * ************************************* LCDTXT: LCDTXT2: PSHA LDAA INX CMPA BEQ CMPA BEQ JSR JSR BRA PULA RTS LDAA JSR JSR BRA

,X #$0A LCDTXT5 #$04 LCDTXT4 LCDTEST LCDWDATA LCDTXT2

LCDTXT4:

* * * * * * * * * *

load pointer to X increment pointer verify if - line change if yes, change the line if end of strig yes, end print test LCD write to LCD next chr. end routine

LCDTXT5:

#$C0 LCDTEST LCDWCTL LCDTXT2

* * * *

Point to case #1 of the line #2 test LCD send new address write in the line #2

************************************* * LCDTEST * * * * Test if LCD is not busy * * * * Reg Aff:CC * ************************************* LCDTEST: PSHA LCDTEST1: JSR BMI PULA RTS

LCDRCTL LCDTEST1

* read the controle register * if busy, test again * end routine

************************************* * LCDRDATA * * * * Data read RS = 1 * * return in A * * * * Reg Aff: A,CC *

142
************************************* * LCDRCTL * * * * Control read RS = 0 * * return in A * * * * Reg Aff: A,CC * ************************************* LCDRDATA: PSHB LDAB BRA LCDRCTL: PSHB LDAB LCDR: PSHX LDX LDAA ANDA ORAA STAA LDAA ANDA ABA TAB STAB BSET NOP LDAA BCLR PSHA STAB BSET NOP LDAA BCLR LSRA LSRA LSRA LSRA PULB ANDB ABA PULX PULB RTS

Microcontrolerul 68HC11. PcBug

#%00000110 LCDR #%00000100

#REGS DDRC,X #%00001111 #%00001110 DDRC,X PC,X #%00000001

* load the PC state I or O * set I and O line of the PC * not bit 0 * read PC value * mask *

PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000

* set E, delay * read data, 4 bit * set E, delay

* set E to 1 + Delay * read data, 4 bit * set E to 0 + Delay

#%11110000

************************************* * LCDWDATA * * * * Write 8 bit from A * * and set RS = 1 * * *

Microprocesoare i Microcontrolere
* Reg Aff: CC * ************************************* * LCDWCTL * * * * Write 8 bit from A * * and set RS = 0 * * * * Reg Aff: CC * ************************************* LCDWDATA: PSHB LDAB BRA LCDWCTL: PSHB LDAB LCDW: PSHX PSHA PSHA LDX PSHA LDAA ORAA STAA LDAA ANDA ABA TAB PULA ANDA ABA STAA BSET BCLR PULA ASLA ASLA ASLA ASLA ABA STAA BSET BCLR PULA PULX PULB RTS

143

#%00000010 LCDW #%00000000

#REGS DDRC,X #%11111110 DDRC,X PC,X #%00000001 * * * * * read the PC state set the PC in write mode store DDRC read the PC value not change the Bit 0

#%11110000 PC,X PC,X %00001000 PC,X %00001000

* set E to 0 and write data (4 bit)

* * * * *

set E to 1 + Delay set E to 0 + Delay pulA for second part Shift second prat data + Delay

PC,X PC,X %00001000 PC,X %00001000

* * * *

set E to set E to pulA for pulX for

1 + Delay 0 + Delay end end

* end routine

************************************* * LCD4BIT * * * * The LCD in 4 bit mode * * *

144
* Reg Aff: CC * ************************************* LCD4BIT: PSHX LDAA BSR BSR BSR BSR BSR BSR BSR BSR BSR BSR LDAA BSR PULX RTS PSHA PSHX PSHB LDX LDAB STAB PULB ANDA STAA BCLR BSET BCLR PULX PULA RTS LDX DEX CPX BNE RTS

Microcontrolerul 68HC11. PcBug

#%00110000 LCD4B2 LCD4B2 LCD4B2 LCD4B2 LCD4B1 LCD4B2 LCD4B1 LCD4B2 LCD4B1 LCD4B2 #%00100000 LCD4B1

* delay 16.4 ms

* * * * * *

set 8 Delay set 8 Delay set 8 Delay

bit 4.1 ms bit 4.1 ms bit 4.1 ms

* set 4 Bit

LCD4B1:

#REGS #%11111111 DDRC,X #%11110000 PC,X PC,X #%00001110 PC,X #%00001000 PC,X #%00001000

* set the DATA in write * store DDRC

* set E & R/W & RS to 0 * set E a 1 * set E a 0

LCD4B2: LCD4B21:

#$0384 #$0000 LCD4B21

* delay

4.5 ms

************************************* * LCDINIT * * * * Set the LCD in mode * * 4 bit 2 line * * Display ON Cursor OFF Blinking OFF* * Clear Display * * Cursor INC, Shift OFF * * * * Reg Aff: A,CC * *************************************

Microprocesoare i Microcontrolere

145

LCDINIT:

JSR LDAA JSR JSR LDAA JSR JSR LDAA JSR JSR LDAA JSR RTS

LCDTEST #%00101000 LCDWCTL LCDTEST #%00001100 LCDWCTL LCDTEST #%00000001 LCDWCTL LCDTEST #%00000110 LCDWCTL

* 4 Bit 2 line

* display ON cursor OFF blink OFF

* clear display

* cursor INC shift OFF

Fiierul surs realizat va trece prin toate etapele de acum cunoscute spre forma obiect ".S19", astfel nct s poat fi ncrcat n memoria EEPROM a microcontrolerului 68HC11. Pentru a vedea programul la lucru vom conecta printrun cablu panglic cele dou module ntre ele. Dac pn acum doar am bnuit c prin interfaa de comunicaii RS232 se face un transfer de informaie ntre calculatorul personal IBM PC (calculator gazd, host) i embedded systemul realizat cu microcontrolerul 68HC11A1 (sistem int, target), n continuare vom realiza un program care s pun n eviden transferul de informaie ntre sistemele prezentate pn acum. Din modul terminal al utilitarului PCBUG (atenie la setarea parametrului de vitez pentru interfaa serial, BAUD) vom trimite diferite mesaje ctre sistemul int pe care acesta le va afia on-line pe LCD. Practic, programul urmtor nu este altceva dect o extensie a programului precedent cu un task orientat spre interfaa serial, adic dup cum spuneam, munc de rutin.
************************************** * PROGRAM "LCDSCI.ASM" * * * * * ************************************** ETX: EQU $04 REGS: EQU $1000 DDRC: EQU $07 PC: EQU $03 BAUD: EQU $2B SCCR1: EQU $2C SCCR2: EQU $2D SCSR: EQU $2E SCDR: EQU $2F * start here ORG $B600

146
LDS JSR JSR LDX JSR JSR RETURLIN: LDAA JSR JSR LDAA JSR LDAA JSR LDAB LOOPSCI: JSR INCB JSR JSR JSR CMPB BEQ JMP #$00FF LCD4BIT LCDINIT #TEXTSCI LCDTXT INISCI #$C0 LCDTEST LCDWCTL #$0A OUTCAR #$0D OUTCAR #$00 INCAR LCDTEST LCDWDATA OUTCAR #$10 RETURLIN LOOPSCI

Microcontrolerul 68HC11. PcBug

* test LCD * send new address

* test LCD * write data to LCD

TEXTSCI:

FCC FCB

'MODE SCI: LINE 2' ETX

************************************** * Set SCI * * 9600 bps, 8 bit, no parity, * * 1 bit sstop * * * * Reg aff: A,CCR * ************************************** INISCI: LDX LDAA STAA LDAA STAA LDAA STAA RTS #REGS #$30 BAUD,X #$00 SCCR1,X #$0C SCCR2,X

* 9600 BPS

* 8 BIT, NO WAKE UP, 1 STOP BIT

* NO INTERRUPT, TX ENABLE, RX ENABLE

************************************* * Send data from A to SCI * * * * * * Reg aff:CCR * *************************************

Microprocesoare i Microcontrolere
OUTCAR: PSHB PSHX LDX LDAB BITB BEQ STAA PULX PULB RTS

147

OUTCAR2:

#REGS SCSR,X #%10000000 OUTCAR2 SCDR,X

************************************* * LOOKCAR * * * * Look the SCI for car. * * * * Z=1, without car. * * Z=0, car. In A register * * * * Reg Aff: A,CCR * ************************************* LOOKCAR: PSHB PSHX LDX LDAB BITB BEQ LDAA PSHA TPA ANDA TAP PULA LOOKCAR1: PULX PULB RTS

#REGS SCSR,X #%00100000 LOOKCAR1 SCDR,X

#%11111011

************************************* * INCAR * * * * Read the SCI * * * * Reg Aff: A,CCR * ************************************* INCAR: JSR BEQ RTS LOOKCAR INCAR

************************************* * ROUTINE FOR NORMAL DIPLAY * * *

148
* X-> pointer to strigt * * end of string $04, * * line control $0A * * if present change the line * * * * Reg aff: X,CCR * ************************************* LCDTXT: LCDTXT2: PSHA LDAA INX CMPA BEQ CMPA BEQ JSR JSR BRA PULA RTS LDAA JSR JSR BRA

Microcontrolerul 68HC11. PcBug

,X #$0A LCDTXT5 #$04 LCDTXT4 LCDTEST LCDWDATA LCDTXT2

LCDTXT4:

* * * * * * * * * *

load pointer to X increment pointer verify if - line change if yes, change the line if end of strig yes, end print test LCD write to LCD next chr. end routine

LCDTXT5:

#$C0 LCDTEST LCDWCTL LCDTXT2

* * * *

Point to case #1 of the line #2 test LCD send new address write in the line #2

************************************* * LCDTEST * * * * Test if LCD is not busy * * * * Reg Aff:CC * ************************************* LCDTEST: PSHA LCDTEST1: JSR BMI PULA RTS

LCDRCTL LCDTEST1

* read the controle register * if busy, test again * end routine

************************************* * LCDRDATA * * * * Data read RS = 1 * * return in A * * * * Reg Aff: A,CC * ************************************* * LCDRCTL * * * * Control read RS = 0 * * return in A * * *

Microprocesoare i Microcontrolere
* Reg Aff: A,CC * ************************************* LCDRDATA: PSHB LDAB BRA LCDRCTL: PSHB LDAB LCDR: PSHX LDX LDAA ANDA ORAA STAA LDAA ANDA ABA TAB STAB BSET NOP LDAA BCLR PSHA STAB BSET NOP LDAA BCLR LSRA LSRA LSRA LSRA PULB ANDB ABA PULX PULB RTS

149

#%00000110 LCDR #%00000100

#REGS DDRC,X #%00001111 #%00001110 DDRC,X PC,X #%00000001

* load the PC state I or O * set I and O line of the PC * not bit 0 * read PC value * mask *

PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000

* set E, delay * read data, 4 bit * set E, delay

* set E to 1 + Delay * read data, 4 bit * set E to 0 + Delay

#%11110000

************************************* * LCDWDATA * * * * Write 8 bit from A * * and set RS = 1 * * * * Reg Aff: CC * ************************************* * LCDWCTL * * * * Write 8 bit from A * * and set RS = 0 *

150
* * * Reg Aff: CC * ************************************* LCDWDATA: PSHB LDAB BRA LCDWCTL: PSHB LDAB LCDW: PSHX PSHA PSHA LDX PSHA LDAA ORAA STAA LDAA ANDA ABA TAB PULA ANDA ABA STAA BSET BCLR PULA ASLA ASLA ASLA ASLA ABA STAA BSET BCLR PULA PULX PULB RTS

Microcontrolerul 68HC11. PcBug

#%00000010 LCDW #%00000000

#REGS DDRC,X #%11111110 DDRC,X PC,X #%00000001 * * * * * read the PC state set the PC in write mode store DDRC read the PC value not change the Bit 0

#%11110000 PC,X PC,X %00001000 PC,X %00001000

* set E to 0 and write data (4 bit)

* * * * *

set E to 1 + Delay set E to 0 + Delay pulA for second part Shift second prat data + Delay

PC,X PC,X %00001000 PC,X %00001000

* * * *

set E to set E to pulA for pulX for

1 + Delay 0 + Delay end end

* end routine

************************************* * LCD4BIT * * * * The LCD in 4 bit mode * * * * Reg Aff: CC * ************************************* LCD4BIT: PSHX LDAA BSR

#%00110000 LCD4B2

* delay 16.4 ms

Microprocesoare i Microcontrolere
BSR BSR BSR BSR BSR BSR BSR BSR BSR LDAA BSR PULX RTS LCD4B1: PSHA PSHX PSHB LDX LDAB STAB PULB ANDA STAA BCLR BSET BCLR PULX PULA RTS LDX DEX CPX BNE RTS LCD4B2 LCD4B2 LCD4B2 LCD4B1 LCD4B2 LCD4B1 LCD4B2 LCD4B1 LCD4B2 #%00100000 LCD4B1

151

* * * * * *

set 8 Delay set 8 Delay set 8 Delay

bit 4.1 ms bit 4.1 ms bit 4.1 ms

* set 4 Bit

#REGS #%11111111 DDRC,X #%11110000 PC,X PC,X #%00001110 PC,X #%00001000 PC,X #%00001000

* set the DATA in write * store DDRC

* set E & R/W & RS to 0 * set E a 1 * set E a 0

LCD4B2: LCD4B21:

#$0384 #$0000 LCD4B21

* delay

4.5 ms

************************************* * LCDINIT * * * * Set the LCD in mode * * 4 bit 2 line * * Display ON Cursor OFF Blinking OFF* * Clear Display * * Cursor INC, Shift OFF * * * * Reg Aff: A,CC * ************************************* LCDINIT: JSR LDAA JSR JSR LDAA LCDTEST #%00101000 LCDWCTL LCDTEST #%00001100

* 4 Bit 2 line

* display ON cursor OFF blink OFF

152
JSR JSR LDAA JSR JSR LDAA JSR RTS LCDWCTL LCDTEST #%00000001 LCDWCTL LCDTEST #%00000110 LCDWCTL

Microcontrolerul 68HC11. PcBug

* clear display

* cursor INC shift OFF

Pentru o mai bun familiarizare cu stilul de programare i instruciunile microcontrolerului 68HC11, n continuare vom realiza o aplicaie independent de calculatorul gazd. Dup ce programul urmtor va fi transferat n sistemul cu 68HC11A1, acesta va funciona independent i nu va fi nimic altceva dect un ceas. Pentru a nu complica inutil programul s-a apelat la un task de ntrziere (delay) chiar dac sistemul dispune de sisteme avansate de temporizare, ntrerupere. Oricum programul urmtor este unic n sistem, aa c, el nu va fi deranjat de alte programe pentru simplul motiv c acestea nu exist. n acest fel, precizia de msurare a timpului nu depinde de elegana metodei utilizate i astfel este posibil s obinem un o aplicaie funcional corect fr prea mari complicaii software. Afiarea timpului la nivel de zecimi de ms cred c sugereaz cam ce poate un asemenea sistem chiar i n aceast versiune minimal.
************************************** * PROGRAM "CLKLCD.ASM" * * * * * ************************************** ETX: EQU $04 REGS: EQU $1000 DDRC: EQU $07 PC: EQU $03 BAUD: EQU $2B SCCR1: EQU $2C SCCR2: EQU $2D SCSR: EQU $2E SCDR: EQU $2F OPT: EQU $39 ADCTL: EQU $30 ADR1: EQU $31 * define variables ORG RMB RMB RMB RMB $0000 1 1 1 1

HREG: MREG: SREG: MSREG:

* * * *

HH:, MM:, SS:, MS,

0 0 0 0

to to to to

23 59 59 99

* start here

Microprocesoare i Microcontrolere

153

LOOPCK:

TICCK:

ORG LDS JSR JSR LDX JSR CLR CLR CLR CLR LDX JSR LDAA ADDA DAA PSHA STAA LDAA JSR JSR JSR PULA CMPA BNE CLR LDAA ADDA DAA STAA CMPA BNE CLR LDAA ADDA DAA STAA CMPA BNE CLR LDAA ADDA DAA STAA CMPA BNE JMP

$B600 #$00FF LCD4BIT LCDINIT #TEXTAD LCDTXT HREG MREG SREG MSREG #8 LDELAY MSREG #1

MSREG #$C0 LCDTEST LCDWCTL TIPTIC #$99 TICCK MSREG SREG #1 SREG #$60 TICCK SREG MREG #1 MREG #$60 TICCK MREG HREG #1 HREG #$24 TICCK LOOPCK

* test LCD * send new address

*************************************** * Routine qui WRITE la valeur de * A au LCD sous la forme BCD ASCII. * * Reg aff:CCR

154
*************************************** LCD2HA: PSHA PSHA LSRA LSRA LSRA LSRA ORA JSR JSR PULA ANDA ORA JSR JSR PULA RTS

Microcontrolerul 68HC11. PcBug

#$30 LCDTEST LCDWDATA #$0F #$30 LCDTEST LCDWDATA

* tiptic TIPTIC: LDX JSR LDAA JSR LDAA JSR JSR LDAA JSR LDAA JSR JSR LDAA JSR LDAA JSR JSR LDAA JSR RTS #TEXTTM LCDTXT HREG LCD2HA #$3A LCDTEST LCDWDATA MREG LCD2HA #$3A LCDTEST LCDWDATA SREG LCD2HA #$3A LCDTEST LCDWDATA MSREG LCD2HA

TEXTAD: TEXTTM:

FCC FCB FCC FCB

'Clock Tick 10 ms' ETX 'Time:' ETX

* LBINBCD:

**************************************

Microprocesoare i Microcontrolere
* LOOP DELAY * * on entry, X = delay in ms * * 286 x 7 x .0005 = 1 ms * ************************************** LDELAY: LDY LOOPDY: DEY BNE DEX BNE RTS #287 LOOPDY LDELAY

155

************************************* * ROUTINE FOR NORMAL DIPLAY * * * * X-> pointer to strigt * * end of string $04, * * line control $0A * * if present change the line * * * * Reg aff: X,CCR * ************************************* LCDTXT: LCDTXT2: PSHA LDAA INX CMPA BEQ CMPA BEQ JSR JSR BRA PULA RTS LDAA JSR JSR BRA

,X #$0A LCDTXT5 #$04 LCDTXT4 LCDTEST LCDWDATA LCDTXT2

LCDTXT4:

* * * * * * * * * *

load pointer to X increment pointer verify if - line change if yes, change the line if end of strig yes, end print test LCD write to LCD next chr. end routine

LCDTXT5:

#$C0 LCDTEST LCDWCTL LCDTXT2

* * * *

Point to case #1 of the line #2 test LCD send new address write in the line #2

************************************* * LCDTEST * * * * Test if LCD is not busy * * * * Reg Aff:CC * ************************************* LCDTEST: PSHA LCDTEST1: JSR BMI PULA

LCDRCTL LCDTEST1

* read the controle register * if busy, test again * end routine

156
RTS ************************************* * LCDRDATA * * * * Data read RS = 1 * * return in A * * * * Reg Aff: A,CC * ************************************* * LCDRCTL * * * * Control read RS = 0 * * return in A * * * * Reg Aff: A,CC * ************************************* LCDRDATA: PSHB LDAB BRA LCDRCTL: PSHB LDAB LCDR: PSHX LDX LDAA ANDA ORAA STAA LDAA ANDA ABA TAB STAB BSET NOP LDAA BCLR PSHA STAB BSET NOP LDAA BCLR LSRA LSRA LSRA LSRA PULB ANDB ABA PULX

Microcontrolerul 68HC11. PcBug

#%00000110 LCDR #%00000100

#REGS DDRC,X #%00001111 #%00001110 DDRC,X PC,X #%00000001

* load the PC state I or O * set I and O line of the PC * not bit 0 * read PC value * mask *

PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000

* set E, delay * read data, 4 bit * set E, delay

* set E to 1 + Delay * read data, 4 bit * set E to 0 + Delay

#%11110000

Microprocesoare i Microcontrolere
PULB RTS ************************************* * LCDWDATA * * * * Write 8 bit from A * * and set RS = 1 * * * * Reg Aff: CC * ************************************* * LCDWCTL * * * * Write 8 bit from A * * and set RS = 0 * * * * Reg Aff: CC * ************************************* LCDWDATA: PSHB LDAB BRA LCDWCTL: PSHB LDAB LCDW: PSHX PSHA PSHA LDX PSHA LDAA ORAA STAA LDAA ANDA ABA TAB PULA ANDA ABA STAA BSET BCLR PULA ASLA ASLA ASLA ASLA ABA STAA BSET BCLR PULA

157

#%00000010 LCDW #%00000000

#REGS DDRC,X #%11111110 DDRC,X PC,X #%00000001 * * * * * read the PC state set the PC in write mode store DDRC read the PC value not change the Bit 0

#%11110000 PC,X PC,X %00001000 PC,X %00001000

* set E to 0 and write data (4 bit)

* * * * *

set E to 1 + Delay set E to 0 + Delay pulA for second part Shift second prat data + Delay

PC,X PC,X %00001000 PC,X %00001000

* set E to 1 + Delay * set E to 0 + Delay * pulA for end

158
PULX PULB RTS ************************************* * LCD4BIT * * * * The LCD in 4 bit mode * * * * Reg Aff: CC * ************************************* LCD4BIT: PSHX LDAA BSR BSR BSR BSR BSR BSR BSR BSR BSR BSR LDAA BSR PULX RTS PSHA PSHX PSHB LDX LDAB STAB PULB ANDA STAA BCLR BSET BCLR PULX PULA RTS LDX DEX CPX BNE RTS

Microcontrolerul 68HC11. PcBug


* pulX for end * end routine

#%00110000 LCD4B2 LCD4B2 LCD4B2 LCD4B2 LCD4B1 LCD4B2 LCD4B1 LCD4B2 LCD4B1 LCD4B2 #%00100000 LCD4B1

* delay 16.4 ms

* * * * * *

set 8 Delay set 8 Delay set 8 Delay

bit 4.1 ms bit 4.1 ms bit 4.1 ms

* set 4 Bit

LCD4B1:

#REGS #%11111111 DDRC,X #%11110000 PC,X PC,X #%00001110 PC,X #%00001000 PC,X #%00001000

* set the DATA in write * store DDRC

* set E & R/W & RS to 0 * set E a 1 * set E a 0

LCD4B2: LCD4B21:

#$0384 #$0000 LCD4B21

* delay

4.5 ms

************************************* * LCDINIT *

Microprocesoare i Microcontrolere
* * * Set the LCD in mode * * 4 bit 2 line * * Display ON Cursor OFF Blinking OFF* * Clear Display * * Cursor INC, Shift OFF * * * * Reg Aff: A,CC * ************************************* LCDINIT: JSR LDAA JSR JSR LDAA JSR JSR LDAA JSR JSR LDAA JSR RTS LCDTEST #%00101000 LCDWCTL LCDTEST #%00001100 LCDWCTL LCDTEST #%00000001 LCDWCTL LCDTEST #%00000110 LCDWCTL

159

* 4 Bit 2 line

* display ON cursor OFF blink OFF

* clear display

* cursor INC shift OFF

Abordarea ntr-un sigur capitol a unor tehnologii extrem de moderne i sofisticate este desigur mai puin productiv. Trebuie s avem ncredere n ceea tim deja din primele ase capitole i s nu uitm c numai acest microcontroler, dac vom putea s-l nvm, ct de ct, n aproximativ o jumtate de an, este o mare realizare. n acest capitol sunt schiate cteva lucruri, un posibil drum de urmat, este nevoie ns de mult voin pentru a ajunge aici. Acum avem la ndemn o tehnologie modern de abordare a aplicaiilor de achiziie de date i control. Deja se contureaz un nou mod de abordare al aplicaiilor total diferit de ceea ce am nvtat n capitolul 4 (pentru portul paralel nu face pmntul s fie rotund aa cum cred tot felul de pseudo-specialiti). Am putut vedea n acest capitol sisteme interconectate ntre ele, fiecare sistem cu propria lui inteligen local respectiv cu propria lui specializare. Aa c, prin prisma tehnologiilor actuale abordarea fiecrei pri a unei aplicaii se face prin intermediul unui hardware-software specializat n care toate componentele concur la obinerea rezultatului final. Achiziia de date, controlul i procesarea distribuit a informaiei a permis realizarea unor aplicaii care pn acum ctiva ani preau de domeniul SF. Astzi ele sunt realitate i pentru multe alte aplicaii aceast tehnologie, n plin dezvoltare, are resurse sau va avea resurse. Tocmai de aceea efortul de a nva merit, este singura posibilitate de a ne oferi o ansa s facem ceva n acest domeniu fr de care, lumea de azi nu s-ar fi deosebit, prea mult, de cea de la nceputul secolului XX.

160

Microcontrolerul 68HC11. PcBug

Microprocesoare i Microcontrolere

161

8. Voltmetru Digital cu Microcontrolerul 68HC11

Nu au fost lipsite de interes aplicaiile din capitolul precedent dac abordm lucrurile din punctul de vedere al unui antrenament cu aceast nou tehnologie. Dup cum am putut constata microcontrolerul 68HC11 are o periferie puternic i dintre toate facilitile oferite de aceast periferie, fr ndoial, cea mai atractiv dintre acestea este convertorul Analog-Digital (A/D). 68HC11 a fost primul microcontroler care a avut nglobat o asemenea periferie. Convertorul A/D utilizeaz o tehnic de conversie oarecum inedit pentru tehnologia clasic, redistribuirea capacitiv de sarcin. Sunt astfel diponibile 8 canale de conversie fiecare cu o rezoluie de 8 bii, rezultatul conversiei fiind obinut prin aproximri succesive cu o acuratee de 1/2 LSB (Least Significant Bit). Pe de alt parte, folosirea unei tehnici de redistribuire capacitiv a sarcinii pentru conversie face inutil utilizarea n aplicaii a unui circuit "sample-hold" extern. Fr a insista asupra caracteristicilor electrice i asupra modului de implementare a tehnicii de conversie amintite n continuare ne vom ndrepta atenia asupra informaiilor necesare pentru utilizarea acestei periferii n aplicaiile de achiziie de date. Pentru a putea realiza conversia A/D a semnalului analogic extern ntr-un domeniu larg (pn la tensiunea de alimentare a microcontrolerului, 5V) pe lng convertorul A/D n 68HC11 mai sunt i dou pompe de sarcin cu ajutorul creia pot fi obinute intern tensiuni de circa 7 - 8 V. Aceste pompe de sarcin trebuie s fie active n dou situaii: atunci cnd este programat memoria EEPROM (fiecare situaie cu pompa de sarcin corespunztoare) i atunci cnd vrem s utilizm covertorul A/D. Pentru a nelege acest mecanism n tabelul 8.1 este prezentat semnificaia biilor din registrul OPTION ($1039).
Tabelul 8.1

Dup cum se poate vedea, ambele pompe sunt selectate cu acelai bit CSEL prin care se asigur semnal de ceas pentru ele. Pompa care furnizeaz tensiune mare pentru comparatoarele convertorului A/D este activat prin intermediul bitului de control ADPU. Pe lng registrul OPTION mai trebuie s tim i s nelegem i semnificaia biilor din registrul ADCTL prezentat n tabelul 8.2. Toi biii din acest

162

Voltmetru Digital cu Microcontrolerul 68HC11

registru pot fi citii sau scrii cu excepia bitului 7 (CCF) care nu poate fi dect citit i a bitului ase care este tot timpul zero. Semnificaia i rolul fiecrui bit este prezentat succint n continuare:
Tabelul 8.2

CCF (Conversion complete Flag) - este setat atunci cnd regitri de rezultat conin o valoare valid obinut n urma conversiei. SCAN (Continuous Scan Control) - dac acest bit este egal cu zero atunci conversia cerut este realizat iar rezultatul este diponibil n regitri destinai acestui scop (ADR1 - ADR4), cnd bitul este egal cu unu atunci convertorul funcioneaz n regim "round-robin" adic depune tot timpul rezultate n regitri ADR1 ADR4 pe msur ce acestea devin disponibile.

Tabelul 8.3

Microprocesoare i Microcontrolere

163

MULT (Multiple-Channel/Single-Channel Control) - dac acest bit este egal cu zero atunci convertorul este configurat pentru a realiza patru conversii succesive a unui singur canal selectat de bii CD - CA ai registrului ADCTL, cnd bitul este egal cu unu atunci convertorul este configurat pentru a realiza conversia pe fiecare canal dintr-un grup de patru canale specificat de bii CD - CC. n acest mod (multiple-channel mode) fiecare canal este asociat cu un registru de canal specific. CD, CC, CB, CA (Channel Selects) - aceti patru bii sunt utilizai pentru a specifica canalul/canalele pe care lucreaz convertorul A/D. Semnificaia lor este prezentat n tabelul 8.3.

Regitrii de rezultat (ADR1 - ADR4) sunt utilizai numai pentru stocarea rezultatelor conversiei A/D, aa c ei sunt de tipul "read-only". Ori de cte ori bitul CCF este egal cu unu, aceti regitri vor conine un rezultat valid care poate fi citit i utilizat prin program. Considernd acest prezentare a convertorului A/D suficient, s realizm n continuare un program prin care s transformm embedded system-ul cu 68HC11 conectat cu modulul LCD ntr-un voltmetru digital pe 8 canale. Folosind utilitarele i comenzile prezentate n capitolul anterior vom obine din fiierul surs prezentat n continuare un fiier obiect tip ".S19" pe care-l vom ncrca n memoria EEPROM a lui 68HC11.
************************************** * PROGRAM "ADLCD.ASM" * * * * * ************************************** ETX: EQU $04 REGS: EQU $1000 DDRC: EQU $07 PC: EQU $03 BAUD: EQU $2B SCCR1: EQU $2C SCCR2: EQU $2D SCSR: EQU $2E SCDR: EQU $2F OPT: EQU $39 ADCTL: EQU $30 ADR1: EQU $31 * define variables ORG RMB RMB $0000 1 3

AREG: BCDBUF:

* tmp storage * $xxxx - dddddd

* start here ORG LDS $B600 #$00FF

164
JSR JSR LDX JSR JSR LDAB LDAA JSR JSR PSHB TBA PSHA ADDA JSR JSR LDX JSR PULA JSR TAB CLRA ASLB BCC LDAA JSR LDAA ANDA ORA JSR JSR LDAA JSR JSR LDAA LSRA LSRA LSRA LSRA ORA JSR JSR LDAA ANDA ORA JSR JSR LDX JSR LDX JSR PULB INCB CMPB LCD4BIT LCDINIT #TEXTAD LCDTXT INIAD #$00 #$C0 LCDTEST LCDWCTL

Voltmetru Digital cu Microcontrolerul 68HC11

NEWAD: LOOPAD:

* test LCD * send new address

#$30 LCDTEST LCDWDATA #TEXTDP LCDTXT ADREAD

* ASCII conversion * test LCD * write to LCD

* value = value x 2, ~5V full scale NOCARRY #$01 BINBCD BCDBUF+1 #$0F #$30 LCDTEST LCDWDATA #$2E LCDTEST LCDWDATA BCDBUF+2

NOCARRY:

* load ms digit

* test LCD * write to LCD * test LCD * write to LCD

#$30 LCDTEST LCDWDATA BCDBUF+2 #$0F #$30 LCDTEST LCDWDATA #TEXTV LCDTXT #2000 LDELAY

* test LCD * write to LCD

* test LCD * write to LCD

#$08

Microprocesoare i Microcontrolere
BEQ JMP JMP FCC FCB FCC FCB FCC FCB NEWADS LOOPAD NEWAD '8 Channels ADC :' ETX ' : ' ETX ' Volts' ETX

165

NEWADS: TEXTAD: TEXTDP: TEXTV:

************************************** * LOOP DELAY * * on entry, X = delay in ms * * 286 x 7 x .0005 = 1 ms * ************************************** LDELAY: LDY LOOPDY: DEY BNE DEX BNE RTS #287 LOOPDY LDELAY

************************************** * BINBCD - BIN to BCD conversion * * Input value in D, * * Conversion value in BCDBUF, ... * ************************************** BINBCD: CLR CLR CLR STAA LDAA SUBD BEQ SUBD STAA LDAA ADDA DAA STAA BCC LDAA ADDA DAA STAA BCC LDAA ADDA DAA STAA BCDBUF BCDBUF+1 BCDBUF+2 AREG AREG #0 XBINBCD #1 AREG BCDBUF+2 #1 BCDBUF+2 TSTD BCDBUF+1 #1 BCDBUF+1 TSTD BCDBUF #1 BCDBUF

TSTD:

166
BCC RTS TSTD

Voltmetru Digital cu Microcontrolerul 68HC11

XBINBCD:

************************************** * Routine for A/D convertor * * * * * ************************************** ************************************** * INIAD * * * * Routine to init * * charge pompe for A/D * * * * * * Reg Aff: A,CCR * ************************************** INIAD: LDX BSET BCLR RTS #REGS OPT,X %10000000 OPT,X %01000000

************************************** * ADREAD * * * * Routine for read value * * conversion from PEx * * * * * * Reg Aff: A,CCR * ************************************** ADREAD: PSHX LDX ANDA STAA LDAA BMI LDAA PULX RTS

ADREAD1:

#REGS #%00001111 ADCTL,X ADCTL,X ADREAD1 ADR1,X

************************************* * ROUTINE FOR NORMAL DIPLAY * * * * X-> pointer to strigt * * end of string $04, * * line control $0A * * if present change the line * * * * Reg aff: X,CCR *

Microprocesoare i Microcontrolere
************************************* LCDTXT: LCDTXT2: PSHA LDAA INX CMPA BEQ CMPA BEQ JSR JSR BRA PULA RTS LDAA JSR JSR BRA

167

,X #$0A LCDTXT5 #$04 LCDTXT4 LCDTEST LCDWDATA LCDTXT2

LCDTXT4:

* * * * * * * * * *

load pointer to X increment pointer verify if - line change if yes, change the line if end of strig yes, end print test LCD write to LCD next chr. end routine

LCDTXT5:

#$C0 LCDTEST LCDWCTL LCDTXT2

* * * *

Point to case #1 of the line #2 test LCD send new address write in the line #2

************************************* * LCDTEST * * * * Test if LCD is not busy * * * * Reg Aff:CC * ************************************* LCDTEST: PSHA LCDTEST1: JSR BMI PULA RTS

LCDRCTL LCDTEST1

* read the controle register * if busy, test again * end routine

************************************* * LCDRDATA * * * * Data read RS = 1 * * return in A * * * * Reg Aff: A,CC * ************************************* * LCDRCTL * * * * Control read RS = 0 * * return in A * * * * Reg Aff: A,CC * ************************************* LCDRDATA: PSHB LDAB BRA

#%00000110 LCDR

168
LCDRCTL: PSHB LDAB PSHX LDX LDAA ANDA ORAA STAA LDAA ANDA ABA TAB STAB BSET NOP LDAA BCLR PSHA STAB BSET NOP LDAA BCLR LSRA LSRA LSRA LSRA PULB ANDB ABA PULX PULB RTS

Voltmetru Digital cu Microcontrolerul 68HC11

#%00000100

LCDR:

#REGS DDRC,X #%00001111 #%00001110 DDRC,X PC,X #%00000001

* load the PC state I or O * set I and O line of the PC * not bit 0 * read PC value * mask *

PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000 PC,X PC,X %00001000

* set E, delay * read data, 4 bit * set E, delay

* set E to 1 + Delay * read data, 4 bit * set E to 0 + Delay

#%11110000

************************************* * LCDWDATA * * * * Write 8 bit from A * * and set RS = 1 * * * * Reg Aff: CC * ************************************* * LCDWCTL * * * * Write 8 bit from A * * and set RS = 0 * * * * Reg Aff: CC * ************************************* LCDWDATA: PSHB LDAB

#%00000010

Microprocesoare i Microcontrolere
BRA PSHB LDAB PSHX PSHA PSHA LDX PSHA LDAA ORAA STAA LDAA ANDA ABA TAB PULA ANDA ABA STAA BSET BCLR PULA ASLA ASLA ASLA ASLA ABA STAA BSET BCLR PULA PULX PULB RTS LCDW #%00000000

169

LCDWCTL:

LCDW:

#REGS DDRC,X #%11111110 DDRC,X PC,X #%00000001 * * * * * read the PC state set the PC in write mode store DDRC read the PC value not change the Bit 0

#%11110000 PC,X PC,X %00001000 PC,X %00001000

* set E to 0 and write data (4 bit)

* * * * *

set E to 1 + Delay set E to 0 + Delay pulA for second part Shift second prat data + Delay

PC,X PC,X %00001000 PC,X %00001000

* * * *

set E to set E to pulA for pulX for

1 + Delay 0 + Delay end end

* end routine

************************************* * LCD4BIT * * * * The LCD in 4 bit mode * * * * Reg Aff: CC * ************************************* LCD4BIT: PSHX LDAA BSR BSR BSR BSR BSR BSR BSR

#%00110000 LCD4B2 LCD4B2 LCD4B2 LCD4B2 LCD4B1 LCD4B2 LCD4B1

* delay 16.4 ms

* set 8 bit * Delay 4.1 ms * set 8 bit

170
BSR BSR BSR LDAA BSR PULX RTS LCD4B1: PSHA PSHX PSHB LDX LDAB STAB PULB ANDA STAA BCLR BSET BCLR PULX PULA RTS LDX DEX CPX BNE RTS LCD4B2 LCD4B1 LCD4B2 #%00100000 LCD4B1

Voltmetru Digital cu Microcontrolerul 68HC11


* Delay 4.1 ms * set 8 bit * Delay 4.1 ms * set 4 Bit

#REGS #%11111111 DDRC,X #%11110000 PC,X PC,X #%00001110 PC,X #%00001000 PC,X #%00001000

* set the DATA in write * store DDRC

* set E & R/W & RS to 0 * set E a 1 * set E a 0

LCD4B2: LCD4B21:

#$0384 #$0000 LCD4B21

* delay

4.5 ms

************************************* * LCDINIT * * * * Set the LCD in mode * * 4 bit 2 line * * Display ON Cursor OFF Blinking OFF* * Clear Display * * Cursor INC, Shift OFF * * * * Reg Aff: A,CC * ************************************* LCDINIT: JSR LDAA JSR JSR LDAA JSR JSR LDAA JSR JSR LDAA LCDTEST #%00101000 LCDWCTL LCDTEST #%00001100 LCDWCTL LCDTEST #%00000001 LCDWCTL LCDTEST #%00000110

* 4 Bit 2 line

* display ON cursor OFF blink OFF

* clear display

* cursor INC shift OFF

Microprocesoare i Microcontrolere
JSR RTS LCDWCTL

171

Chiar i n aceast implementare minimal a unui embedded system cu microcontrolerul 68HC11 se poate uor implementa un sistem distribuit de achiziie de date. Utiliznd cu pricepere comanda "copy - paste" a editorului nu a fost greu s realizm programele anterioare. Programele pentru microcontrolerul 68HC11 prezentate pn acum au multe subrutine comune care pur i simplu au fost copiate dintr-un program n altul, acesta este marele avantaj a utilizrii unui asamblor extern. Utiliznd cu pricepere aceast facilitate, n scurt timp putem obine fiierul surs prezentat n continuare:
************************************** * PROGRAM "ADSCI.ASM" * * * * * ************************************** ETX: EQU $04 REGS: EQU $1000 DDRC: EQU $07 PC: EQU $03 BAUD: EQU $2B SCCR1: EQU $2C SCCR2: EQU $2D SCSR: EQU $2E SCDR: EQU $2F OPT: EQU $39 ADCTL: EQU $30 ADR1: EQU $31 * define variables ORG RMB RMB $0000 1 3

AREG: BCDBUF:

* tmp storage * $xxxx - dddddd

* start here ORG LDS JSR JSR JSR PSHA PSHA LDAA JSR LDAA JSR PULA $B600 #$00FF INISCI INIAD INCAR

LOOPAD:

#$0A OUTCAR #$0D OUTCAR

172
JSR LDAA JSR PULA SUBA JSR TAB CLRA ASLB BCC LDAA JSR LDAA ANDA ORA JSR LDAA JSR LDAA LSRA LSRA LSRA LSRA ORA JSR LDAA ANDA ORA JSR JMP OUTCAR #$3A OUTCAR #$30 ADREAD

Voltmetru Digital cu Microcontrolerul 68HC11

* channel 0 to 7

* value = value x 2, ~5V full scale NOCARRY #$01 BINBCD BCDBUF+1 #$0F #$30 OUTCAR #$2E OUTCAR BCDBUF+2

NOCARRY:

* load ms digit

#$30 OUTCAR BCDBUF+2 #$0F #$30 OUTCAR LOOPAD

************************************** * BINBCD - BIN to BCD conversion * * Input value in D, * * Conversion value in BCDBUF, ... * ************************************** BINBCD: CLR CLR CLR STAA LDAA SUBD BEQ SUBD STAA LDAA ADDA DAA STAA BCC LDAA ADDA BCDBUF BCDBUF+1 BCDBUF+2 AREG AREG #0 XBINBCD #1 AREG BCDBUF+2 #1 BCDBUF+2 TSTD BCDBUF+1 #1

TSTD:

Microprocesoare i Microcontrolere
DAA STAA BCC LDAA ADDA DAA STAA BCC RTS

173

BCDBUF+1 TSTD BCDBUF #1 BCDBUF TSTD

XBINBCD:

************************************** * Routines for A/D converter * * * * * ************************************** ************************************** * INIAD * * * * Routine for A/D init * * * * charge pompe on * * * * Reg Aff: A,CCR * ************************************** INIAD: LDX BSET BCLR RTS #REGS OPT,X %10000000 OPT,X %01000000

************************************** * ADREAD * * * * Routine for read A/D value * * from PEx channel * * * * * * * * Reg Aff: A,CCR * ************************************** ADREAD: PSHX LDX ANDA STAA LDAA BMI LDAA PULX RTS

ADREAD1:

#REGS #%00001111 ADCTL,X ADCTL,X ADREAD1 ADR1,X

**************************************

174

Voltmetru Digital cu Microcontrolerul 68HC11

* Init SCI * * * * 9600 bps, 8 bit, no parity, * * 1 stop bit * * * * Reg aff: A,CCR * ************************************** INISCI: LDX LDAA STAA LDAA STAA LDAA STAA RTS #REGS #$30 BAUD,X #$00 SCCR1,X #$0C SCCR2,X

* 9600 BPS

* 8 BIT, NO WAKE UP, 1 STOP BIT

* NO INTERRUPT, TX ENABLE, RX ENABLE

************************************* * Send value from A to SCI * * * * * * Reg aff:CCR * ************************************* OUTCAR: PSHB PSHX LDX LDAB BITB BEQ STAA PULX PULB RTS

OUTCAR2:

#REGS SCSR,X #%10000000 OUTCAR2 SCDR,X

************************************* * LOOKCAR * * * * test char * * if available * * * * Z=1, not car. * * Z=0, car. into A * * * * Reg Aff: A,CCR * ************************************* LOOKCAR: PSHB PSHX LDX LDAB

#REGS SCSR,X

Microprocesoare i Microcontrolere
BITB BEQ LDAA PSHA TPA ANDA TAP PULA LOOKCAR1: PULX PULB RTS #%00100000 LOOKCAR1 SCDR,X

175

#%11111011

************************************* * INCAR * * * * Read char. From SCI * * * * * * Reg Aff: A,CCR * ************************************* INCAR: JSR BEQ RTS LOOKCAR INCAR

De aceast dat, prin rularea programului anterior pe embedded system-ul cu microcontrolerul 68HC11 realizm o interaciune puternic ntre sistemul gazd i sistemul int. Astfel, sistemul gazd trimite prin interfaa serial o cerere de conversie pe unul din cele 8 canale ale convertorului A/D, iar sistemul int rspude prin acelai canal de comunicaie cu valoarea tensiuni, de pe acel canal, exprimat n voli i convertit n zecimal. Aceast situaie poate fi pus n eviden prin intermediul utilitarului PCBUG n modul terminal. La fel de bine se poate scrie un program pentru calculatorul gazd care s implementeze acest protocol de comunicaie i astfel s obinem un sistem distribuit de achiziie de date. Desigur n acest moment se pot imagina multe aplicaii concrete pe baza acestei tehnologii. Dar nu orice se poate face cu acest embedded system minimal, el este foarte bun pentru rezolvarea unor situaii relativ simple i este foarte bun pentru a ne instrui n acest domeniu. Pentru aplicaii mai pretenioase este necesar mai mult memorie i/sau mai multe porturi de I/O. Dup cum am menionat n capitolul anterior, microcontrolerul 68HC11 poate lucra i n mod "Expanded". O asemenea configuraie hardware care pstreaz n continuare avantajele "autoboot" ale microcontrolerului este prezenat n figura 8.1. n aceast versiune dispunem de o memorie SRAM de 32Kbyte suficient pentru programe complexe respectiv pentru manipularea unui volum relativ mare de date. De asemenea, se asigur o structur

176

Voltmetru Digital cu Microcontrolerul 68HC11

de dezvoltare de tip "open aplication" suficient de flexibil att la nivel hardware ct mai ales la nivel software.

Figura 8.1.Realizarea practic a versiunii "Expanded" a microcontrolerului 68HC11.

Este bine s menionm c pentru acest hardware au fost adaptate o serie de interpretoare pentru limbaje de nivel nalt cum ar fi C, Basic, Forth. A fost testat, de asemenea cu succes, o versiune adaptat a celebrului monitor BUFALO utilizat de firma Motorola pentru propriile sisteme de dezvoltare. Acesta nu este altceva dect un utilitar gen PCBUG numai c de aceast dat sunt utilizate resursele embedded system-ului pentru realizarea tuturor comenzilor calculatorul gazd find un simplu terminal. Posibilitatea de a lucra direct n limbaje de nivel nalt prin intermediul unor interpretoare coninute n sistem duce la creterea productivitii atunci cnd avem aplicaii nu prea pretenioase n raport cu viteza de execuie mic a unui program interpretat. Desigur, sunt disponibile i compilatoare pentru limbajele de nivel nalt menionate anterior cu ajutorul crora se poate obine uor versiunea cod main (.S19) urmat de o cretere semnificativ a performanelor. Dac nici aa nu putem s satisfacem foamea de vitez a unei aplicaii nu trebuie s uitm c n aceste dou capitole am facut deja un contact dur cu limbajul de asamblare al microcontrolerului 68HC11. Microcontrolerul 68HC11 a fost i este un proiect foarte reuit al firmei Motorola i n acelai timp, unul dintre cele mai reuite microcontrolere de uz general produse pn n prezent n gama de 8 bii. Nu n orice aplicaie avem ns

Microprocesoare i Microcontrolere

177

nevoie de o periferie att de bine reprezentat i att de flexibil. Dup cum vom vedea n capitolul urmtor, se poate i altfel. Astzi exist pe pia o ofert extrem de bogat de microcontrolere, fiecare familie avnd zeci de versiuni. De altfel fiecare firm dezvolt simultan cteva familii (de regul pn n zece) i de asemenea pot fi considerate active cel putin zece mari firme n acest domeniu. De multe ori este greu s alegi cea mai bun soluie pentru o aplicaie dat. Pe de alt parte, sunt prezente pe pia microcontrolere de 4, 8, 16, i 32 de bii ntr-o mare varietate i un domeniu extrem de larg n ceea ce privete performanele. Astfel sunt disponibile microcontrolere care cu greu pot controla un LED sau microcontrolere att de evoluate i specializate nct cu nu de puine ori eti tentat s crezi c n faa ta un monstru sacru se d n spectacol. Dup cum am constatat din aplicaiile de pn acum, lumea Motorola este substanial diferit de lumea Intel. Care este mai frumoas ? Care este mai bun ? Greu de spus.

178

Voltmetru Digital cu Microcontrolerul 68HC11

Microprocesoare i Microcontrolere

179

9. Microcontrolerul PIC16F84

Microcontrolerul PIC16F84 face parte din grupul PIC16FXX al familiei PIC16CXX i este un produs al firmei MicroChip. Aceast familie de microcontrolere respectiv microcontrolerul PIC16F84 a devenit n timp extrem de popular n aria aplicaiilor cu un buget redus. Succesul microcontrolerului PIC16F84 (figura 9.1) se datoreaz att preului extrem de sczut, ct i arhitecturii avansate de tip RISC (Reduced Set Instruction Computer, numai 35 de instruciuni) fiind realizat ntr-o tehnologie CMOS. Microcontrolerul PIC16F84 este de tip static nct permite funcionarea de la DC pn la frecvene ale ceasului de maxim 20 MHz. Spre deosebire de microcontrolerul 68HC11 prezentat n capitolul 7 (care are drept surs de inspiraie familia clasic de microprocesoare de 8 bii de la firma Motorola) care este de tip CISC (Complex Set Instruction Computer) cu o arhitectur clasic (von Neumman), PIC16F84 are o arhitectur Harvard cu o magistral de instruciuni de 14 bii (instruciunile sunt organizate pe cuvinte de 14 bii) i o magistral separat de date de 8 bii. Cu excepia instruciunilor de salt toate celelalte instruciuni sunt executate ntr-un singur ciclu graie unui "pipiline" n dou etape. Toate acestea fac ca PIC16F84 s fie cel mai rapid microcontroler din clasa sa.

Figura 9.1. Diverse variante ale microcontrolerului PIC16F84.

180

Microcontrolerul PIC16F84

Microcontrolerul PIC16F84 a fost proiectat cu scopul obinerii unui raport maxim simplitate/performan. Astfel, el are o o stiv intern pe 8 nivele i multiple surse de ntrerupere att interne ct i externe. De asemenea, dispune pe lng memoria program FLASH de 1Kword (un word este de 14 bii) de o memorie de date (organizat pe 8 bii) compus dintr-un RAM de 64 bytes i un EEPROM de 64 bytes. PIC16F84 este uor de confundat cu un banal circuit integrat, deoarece fizic este o capsul cu doar 18 pini, figura 9.2.

Figura 9.2. Diagrama pinilor pentru microcontrolerul PIC16F84.

Dintre acetia doar 13 pini pot fi utilizai pentru operaii de I/O, aa c microcontrolerul nu permite o prea mare varietate de configuraii (adic are numai mod Single-Chip) i din acest punct de vedere a fost realizat cu scopul utilizrii unui minim de componente ntr-o aplicaie dat. Aa se explic cele patru opiuni pentru oscilatorul de ceas intern. Microcontrolerul PIC16F84 poate folosi n aplicaiile ieftine o configuraie extern RC a oscilatorului conectat la un singur pin sau se poate opta pentru o configuraie LP (Low Power consumption) a acestuia. Aplicaiile pretenioase n modul XT pot utiliza pe post de rezonator un cristal standard sau un cristal de mare vitez pentru modul HS. O alt soluie elegant rezolvat la acest microcontroler este circuitul intern "Watchdog" care beneficiaz de un oscilator RC separat coninut i acesta n structura sa intern, prin aceast structur se poate prentmpina situaiile de blocare

Microprocesoare i Microcontrolere

181

software ale microcontrolerului. Posibilitatea de a fi programat n circuit prin intermediul a numai doi pini simplific depanarea programelor sau operaiile de upgrade pentru programe - aplicaii. Cu toate acestea, este nevoie de un programator extern (dispozitiv hardware specializat) care trebuie s fie de asemenea diponibil n cutia noastr de scule. De asemenea, prezena i a unei memorii interne de tip EEPROM pentru date permite o uoar implementare a operaiilor de calibrare, respectiv o uoar modificare a acestor date pe parcursul dezvoltrii unei aplicaii.

Figura 9.3. Arhitectura intern a microcontrolerului PIC16F84.

nainte de a folosi acest microcontroler, trebuie s citim cu atenie documentaia oferit de firma MicroChip. Acest capitol nu face altceva dect s ne clarifice unele aspecte de ordin general i s ne traseze un posibil drum n aborarea microcntrolerelor de tip RISC. Arhitectura intern a microcontrolerului PIC16F84 este prezentat n figura 9.3.

182

Microcontrolerul PIC16F84

Aceast arhitectur (Harvard) este specific oricrui microcontroler de tip RISC i se distinge prin accesarea programului i a datelor din memorii diferite. Aceast separare a memoriilor i evident a magistralelor aferente a permis realizarea unor microcontrolere cu cuvinte de mrime diferit pentru instruciuni i respectiv pentru date. Toate acestea sunt completate de un set de instruciuni orthogonal (simetric), adic, un set de instruciuni (anexa C) care permite folosirea cu orice registru a oricrui mod de adresare. Aceast simetrie a setului de instruciuni permite att o programare eficient a microcontrolerului PIC16F84 ct i posibilitatea realizrii unor compilatoare att de eficiente, pentru limbajele de nivel nalt (de regul pentru C), nct practic nu mai face necesar programarea n limbaj de asamblare dect n unele situaii cu totul excepionale. Din punctul de vedere al programatorului este important cunoaterea modului de organizare a memoriei i a regitrilor (figura 9.4) n cazul microcontrolerului PIC16F84.

Figura 9.4. Modul de organizare a memoriei i a regitrilor microcontrelerului PIC16F84

Microprocesoare i Microcontrolere

183

De asemenea este important cunoaterea set-rilor i funciilor ce pot fi activate prin intermediul acestora. Tabelul 9.1 preluat din documentaia original prezint ntr-o form condensat regitri de baz ai microcontrolerului PIC16F84.
Tabelul 9.1

Pentru efectuarea unor experiene cu acest microcontroler, mai nti trebuie s realizm o implementare hardware, fie i minimal, a acestuia. O asemenea implementare pentru microcontrolerul PIC16F84 cu faciliti de programare n circuit este prezentat n figura 9.5. Cel mai folosit programator pentru proiecte mici care folosesc microcontrolerul PIC16F84 este cunoscut sub numele de JDM (sau LUPIDO), iar despre acest programator pot fi gsite pe Internet suficiente informaii nct s poat fi realizat. De asemenea, sunt disponibile gratuit pe Internet o serie de programe care lucreaz cu acest tip de programator sau care pot fi uor set-ate pentru utilizarea cu JDM. Acest programator lucreaz pe interfaa serial RS232 i nu are nevoie de o surs extern de energie. Dac preocuprile noastre se reduc la folosirea acestui tip de microcontroler (PIC16F84) programatorul JDM poate fi o soluie acceptabil. De

184

Microcontrolerul PIC16F84

asemenea, pe Internet sunt disponibile informaii despre programatoare mult mai sofisticate care pot programa o arie mai mare de astfel de circuite. Nu n ultimul rnd, trebuie menionate programatoarele produse de firma MicroChip care se adreseaz unui public avizat.

Figura 9.5. Realizarea practic a sistemului cu microcontrolerul PIC16F84.

Dup cum am menionat anterior, pentru programarea acestei clase de microcontrolere (cu simetrie ridicat pentru setul de instruciuni) se poate folosi cu foarte bune performane limbajul C. Desigur, compilatorul (precum i mediul de programare) este adaptat la caracteristicile acestor microcontrolere i ca atare, un prim contact cu aceast implementare a limbajului C poate prea neconform cu versiunea clasic. n continuare, discuia va face referin la mediul de programare C2C destinat microcontrolerelor produse de firma MicroChip. Astfel, sunt acceptate urmtoarele faciliti ale standardului C:
if, else, while, for, return, break, continue, extern, switch, case, default; goto and labels; char, short, int, long, void; ~, ++, --, +, -, <, <=, >, >=, ==, !=, =, !, &, |, ^, &=, |=, ^=, &&, ||, *, /, %, <<, >>, <<=, >>=; one-dimensional arrays; const char pointers; const variables and arrays;

Microprocesoare i Microcontrolere
functions with no/one/many parameters and void/char return type; built-in assembler; #include #define, #undef #ifdef, #ifndef, #else, #endif

185

De asemenea, compilatorul recunoate urmtoarele variabile, fr a fi explicit declarate:


INDF ind f register( 0x00 ) TMR0 8-bit real-time clock/counter( 0x01 ) PCL low order 8 bits program counter( 0x02, 0x82 ) STATUS status register( 0x03, 0x83 ) FSR indirect data memory address pointer( 0x04, 0x84 ) PORTA port A( 0x05 ) PORTB port B( 0x06 ) EEDATA EEPROM data register( 0x08 ) EEADRE EPROM address register( 0x09 ) PCLATH high order 5 bits program counter( 0x0A, 0x8A ) INTCON intcon register( 0x0b, 0x8b ) OPTION_REG option register( 0x81 ) TRISA port A data direction register( 0x85 ) TRISB port B data direction register( 0x86 ) EECON1 EEPROM control register( 0x88 ) EECON2 EEPROM control register( 0x89 )

Suport variabile de 8 i 16 bii, care pot fi definite ca variabile locale sau ca variabile globale. Variabilele locale vor utiliza acelai spaiu de memorie aa c utilizarea acestora este ncurajat. De asemenea, sunt acceptate urmtoarele tipuri de date:
Data Decimal Octal Hexadecimal Binary ASCII Type Syntax XXXXX 0XXXX 0xXXXX XXXXXb 'X' Example 1563 0234 0xFFA8 10000001b 'S'

Dup cum tim, limbajul C este orientat spre conceptul de funcie, aa c, este bine s reinem cteva faciliti ale versiunii C2C n raport cu acest aspect. Avem urmtoarele funcii speciale:
main interrupt

186

Microcontrolerul PIC16F84

precum i funcii predefinite care uureaz mult programarea acestei clase de microcontrolere:
clear_wdt enable_interrupt disable_interrupt set_mode set_option set_tris_a set_tris_b set_tris_c output_port_a output_port_b output_port_c output_high_port_a output_high_port_b output_high_port_c output_low_port_a output_low_port_b output_low_port_c input_port_a input_port_b input_port_c input_pin_port_a input_pin_port_b input_pin_port_c sleep nop set_bit clear_bit putchar getchar delay_s delay_ms delay_us char_to_bcd bcd_to_char

Mult mai multe informaii pot fi obinute din help-ul on-line care este parte a mediului de programare C2C. Vom lansa n execuie mediul C2C pentru a realiza un program n limbajul C care va face s plpie LED-ul de pe linia RB7 (figura 9.5). Cu ajutorul editorului din mediul de programare C2C vom deschide fiierul Flashtst.c din folderul Samples:
//This test program for the PIC 16F84 target shows how to use //flash and uses 'write_flash' and 'write_flash' calls

Microprocesoare i Microcontrolere
//provided in the 'flash.c' file //The flash from 0 to FLASH_SIZE is filled and tested //by numbers. By the end the blinkind of the LED //connected to B7 indicates success and blinking //of all LEDs connected to B0-B7 indicates failure #include "flash.c" #define FLASH_SIZE 64 #pragma CLOCK_FREQ 4000000 main() { char i, a, err = 0; disable_interrupt( GIE ); set_bit( STATUS, RP0 ); set_tris_b( 0 ); clear_bit( STATUS, RP0 ); output_port_b( 0 ); for( i = 0; i < FLASH_SIZE; i++ ) { write_flash( i, i*2 ); a = read_flash( i ); if( a != i*2 ) { err = 1; break; } } while( 1 ) { if( err ) { output_port_b( 0 ); delay_ms( 250 ); output_port_b( 255 ); } else { output_high_port_b( 7 ); delay_ms( 250 ); output_low_port_b( 7 ); } delay_ms( 250 ); } }

187

188

Microcontrolerul PIC16F84

Deoarece programul anterior va include n timpul compilrii i fiierul flash.c, pentru o mai bun nelegere a modului de programare n limbaj C a acestei clase de microcontrolere l vom deschide i pe acesta (l vom gsi n acelai folder).
//the memory bank 0 should be selected void write_flash( char addr, char data ) { //Write flash EEADR = addr; EEDATA = data; set_bit( STATUS, RP0 ); set_bit( EECON1, WREN ); EECON2 = 0x55; EECON2 = 0xAA; set_bit( EECON1, WR ); while(EECON1&2); clear_bit( EECON1, WREN ); clear_bit( STATUS, RP0 ); } char read_flash( char addr ) { //Read flash EEADR = addr; set_bit( STATUS, RP0 ); set_bit( EECON1, RD ); clear_bit( STATUS, RP0 ); asm movf EEDATA, W } /* EOF ********************/

Dup compilarea programului, vom obine versiunea n limbaj de asamblare a programului scris n limbajul C. Pentru a ne familiariza ct de ct cu limbajul de asamblare a acestui microcontroler este prezentat n continuare aceast form a programului.
; This file was generated by C2C-plus compiler version 4.00.7e include "p16F876.inc" ;Variables ***************************************** _code_tmp_0000 equ 0x70 _code_tmp_0001 equ 0x71 _code_tmp_0002 equ 0x72 param00_delay_ms equ 0x73 param00_write_flash equ 0x75 param01_write_flash equ 0x76

Microprocesoare i Microcontrolere
param00_read_flash _i_main _a_main _err_main ORG 0 clrf PCLATH goto start__code ORG 4 _interrupt bcf INTCON, T0IF retfie equ equ equ equ 0x77 0x78 0x79 0x7a

189

;clear interrupt flag

_write_flash goto _write_flash__code _read_flash goto _read_flash__code _delay_ms goto _delay_ms__code start__code _main__code clrf _err_main bcf INTCON, GIE bsf STATUS, RP0 bsf STATUS, RP0 bcf STATUS, RP1 clrf TRISB bcf STATUS, RP0 bcf STATUS, RP0 clrf PORTB clrf _i_main label_0002 movlw D'64' subwf _i_main, W movlw 1 btfsc STATUS, C clrw sublw 0 btfsc STATUS, Z goto label_0003 movf _i_main, W movwf param00_write_flash clrf _code_tmp_0000 movlw D'9' movwf _code_tmp_0002 movf _i_main, W movwf _code_tmp_0001 movlw D'2' bcf STATUS, C label_0004 rrf _code_tmp_0000 , F rrf _code_tmp_0001 , F btfsc STATUS, C

190
addwf _code_tmp_0000 , F decfsz _code_tmp_0002 , F goto label_0004 movf _code_tmp_0001 , W movwf param01_write_flash call _write_flash bcf PCLATH, 3 bcf PCLATH, 4 movf _i_main, W movwf param00_read_flash call _read_flash bcf PCLATH, 3 bcf PCLATH, 4 movwf _a_main clrf _code_tmp_0000 movlw D'9' movwf _code_tmp_0002 movf _i_main, W movwf _code_tmp_0001 movlw D'2' bcf STATUS, C label_0006 rrf _code_tmp_0000 , F rrf _code_tmp_0001 , F btfsc STATUS, C addwf _code_tmp_0000 , F decfsz _code_tmp_0002 , F goto label_0006 movf _code_tmp_0001 , W subwf _a_main, W btfsc STATUS, Z goto label_0007 movlw 1 goto label_0008 label_0007 movf _code_tmp_0000 , W sublw 0 movlw 1 btfsc STATUS, Z clrw label_0008 sublw 0 btfsc STATUS, Z goto label_0005 movlw D'1' movwf _err_main goto label_0003 label_0005 incf _i_main, F goto label_0002 label_0003 label_0009 movf _err_main, W

Microcontrolerul PIC16F84

Microprocesoare i Microcontrolere
btfsc STATUS, Z goto label_0011 bcf STATUS, RP0 bcf STATUS, RP1 clrf PORTB movlw D'250' movwf param00_delay_ms call _delay_ms bcf PCLATH, 3 bcf PCLATH, 4 movlw D'255' bcf STATUS, RP0 bcf STATUS, RP1 movwf PORTB goto label_0014 label_0011 bcf STATUS, RP0 bcf STATUS, RP1 bsf PORTB, 7 movlw D'250' movwf param00_delay_ms call _delay_ms bcf PCLATH, 3 bcf PCLATH, 4 bcf STATUS, RP0 bcf STATUS, RP1 bcf PORTB, 7 label_0014 movlw D'250' movwf param00_delay_ms call _delay_ms bcf PCLATH, 3 bcf PCLATH, 4 goto label_0009 label_0010 _main__end _write_flash__code movf param00_write_flash, W bcf STATUS, RP0 bcf STATUS, RP1 movwf EEADR movf param01_write_flash, W movwf EEDATA bsf STATUS, RP0 bsf STATUS, RP0 bsf EECON1, WREN movlw D'85' movwf EECON2 movlw D'170' movwf EECON2 bsf EECON1, WR label_0000 bsf STATUS, RP0

191

192
bcf STATUS, RP1 btfss EECON1, 1 goto label_0001 goto label_0000 label_0001 bsf STATUS, RP0 bcf STATUS, RP1 bcf EECON1, WREN bcf STATUS, RP0 return _write_flash__end _read_flash__code movf param00_read_flash, W bcf STATUS, RP0 bcf STATUS, RP1 movwf EEADR bsf STATUS, RP0 bsf STATUS, RP0 bsf EECON1, RD bcf STATUS, RP0 bcf STATUS, RP0 movf EEDATA, W return _read_flash__end _delay_ms__code label_0012 movlw D'142' movwf param00_delay_ms+1 nop nop label_0013 nop nop nop nop decfsz param00_delay_ms+1, 1 goto label_0013 nop decfsz param00_delay_ms, 1 goto label_0012 nop return _delay_ms__end END

Microcontrolerul PIC16F84

Urmtoarea operaie este apelarea asamblorului care plecnd de la forma n limbaj de asamblare a programului va genera codul ce trebuie ncrcat n memoria microcontrolerului PIC16F84. n figura 9.6 este prezentat mediul de lucru C2C dup parcurgerea tuturor etapelor menionate anterior. Atenie asamblorul (MPASM) nu este inclus n mediul de programare, el poate fi gsit pe site-ul firmei MicroChip ca parte a mediului de programare MPLAB.

Microprocesoare i Microcontrolere

193

Figura 9.6. Mediul de programare C2C.

n acest moment avem fiierul (Flashtst.hex) cu codul ce trebuie ncarcat n memoria microcontrolerului PIC16F84, cu ajutorul unui programator extern, n format HEX. Coninutul acestui fiier este urmtorul:
:040000008A01092840 :080008000B11090076288E2877 :100010009928FA018B138316831603138601831222 :1000200083128601F8014030780201300318030181 :10003000003C031955287808F500F0010930F2005A :100040007808F10002300310F00CF10C0318F007EF :10005000F20B24287108F60006208A110A1278088B :10006000F70007208A110A12F900F0010930F200A6 :100070007808F10002300310F00CF10C0318F007BF :10008000F20B3C28710879020319482801304D28E9 :100090007008003C013003190301003C0319532888 :1000A0000130FA005528F80A13287A080319652840 :1000B000831203138601FA30F30008208A110A1212 :1000C000FF308312031386007028831203138617F0 :1000D000FA30F30008208A110A12831203138613E0 :1000E000FA30F30008208A110A1255287508831285 :1000F00003138D0076088C00831683160C1555307B :100100008D00AA308D008C14831603138C1C892853

194
:100110008428831603130C118312080077088312B6 :1001200003138D00831683160C14831283120C089C :1001300008008E30F4000000000000000000000005 :100140000000F40B9D280000F30B99280000080024 :00000001FF

Microcontrolerul PIC16F84

Ultima etap const n programarea microcontrolerului PIC16F84 cu ajutorul unui programator extern. Pentru aceasta vom lansa n execuie unul din programele care poate interaciona cu programatorul extern pe care-l avem. Acesta este conectat pe interfaa serial RS232 sau la Portul Paralel al calculatorului IBM PC. Totul depinde de tipul i performanele programatorului de care dispunem. Pentru a ne face o idee despre programarea microcontrolerului PIC16F84 n figura 9.7 este prezentat un caz particular pentru aceast etap.

Figura 9.7. Programarea microcontrolerului PIC16F84.

Pentru a ne convinge de buna funcionare a programului i/sau a sistemului, microcontrolerul programat va fi mutat dup programare pe placa sistemului de dezvoltare din figura 9.5 sau a oricrui alt sistem de dezvoltare pentru PIC16F84. Alimentm montajul i LED-ul trebuie s plpie. Toate aceste etape va trebui s le

Microprocesoare i Microcontrolere

195

parcurgem de foarte multe ori, mai ales la nceputurile meseriei, deoarece vom face multe greeli i vom uita tot felul de amnunte. Nu de puine ori produsul experienelor noastre n acest domeniu nu va fi nimic altceva dect un fum negru, greu i neccios. Mult este pn putem s controlm un simplu LED.

196

Microcontrolerul PIC16F84

Microprocesoare i Microcontrolere

197

A. Setul de Instruciuni al Familiei de Microprocesoare 80X86

n aceast anex va fi prezentat i analizat succint setul de instruciuni al microprocesoarelor Intel ncepnd cu versiunea 8086 i teminnd cu versiunea Pentium. O prezentare n detaliu i complet a setului de instruciuni a microprocesorelor Intel 80X86 n evoluia lor necesit cu siguran un spaiu de cel puin zece ori mai mare dect cel oferit de aceast carte n ntregul ei. Scopul ntregii cri este atingerea stadiului de novice n domeniul embedded system, aa c amnuntele legate de setul de instruciuni a microprocesoarelor Intel 80X86 cu toate ciudenile lor, impuse de compatibilitatea de sus n jos, nu fac obiectul acestui material. De altfel dup cum se poate constata din aplicaiile prezentate n aceast carte pentru scrierea unei proceduri software avem cel puin teoretic o infinitate de variante, aa c practica a dovedit c fiecare programator scrie programele apelnd la un set restrns de instruciuni. Plecnd i de la aceast realitate compilatoarele limbajelor de nivel nalt au evoluat spre maina standard, i desigur aceste tendine au dus la inovaii importante n hardware nct astzi, practic, competiia a fost tranat n favoarea microprocesoarelor cu set restrns de instruciuni (RISC, Reduced Instruction Set Computer). Aceast reorientare a permis microprocesoarelor Intel 80X86 o cretere spectaculoas a performanelor, limitat desigur n primul rnd de blestemul compatibilitii cu primele versiuni CISC (Complex Instruction Set Computer). Instruciunile limbajului de asamblare (mnemonice) sunt alctuite cu scopul de a descrie fiecare operaie pe care o poate executa microprocesorul. Programele scrise n limbaj de asamblare sunt denumite cod surs. Fiecare instruciune din programul surs corespunde unei declaraii n limbaj de asamblare. Declaraia trebuie s specifice care operaie va fi executat i care operand data va fi procesat. Pe acest considerent o instruciune poate fi divizat n dou pri distincte, o parte opcode i o parte operand. Aa c prin opcode vom nelege aceea parte a instruciuni prin care se indentific operaia ce va fi executat, iar prin operand vom nelege partea instruciuni care indentific data care va fi procesat.
INSTRUCIUNE = OPCODE + OPERAND EXEMPLU ADD AX, BX

n exemplul precedent ADD este opcode. Coninutul regitrilor AX i BX este adunat iar suma obinut este depus n registrul AX. Registrul BX este considerat operand-ul surs iar registru AX este considerat operand-ul destinaie.

198

Setul de Instruciuni al Familiei de Microprocesoare 80X86

Prin asamblor nelegem un program care face conversia din limbaj de asamblare surs n cod obiect, limbaj masin. Prin modurile de adresare nelegem un set de mecanisme prin care o instruciune specific cum este obinut operand-ul surs eventual destinaie. Modurile de adresare disponibile pentru microprocesorul 8086 sunt:
Adresare Registru Adresare Imediat Adresare Direct Adresare Indirect prin Registru Adresare Bazat Adresare Indexat Adresare Bazat Indexat Adresare ir Adresare Port.

n modul de adresare registru operand-ul este accesat prin specificarea registrului n care acesta se afl. De exemplu prin instruciunea MOV AX,BX coninutul registrului BX, operand-ul surs, este transferat n operand-ul destinaie, registrul AX. Att operand-ul surs ct i operand-ul destinaie sunt specificai ca i coninut a unor regitri interni din microprocesorul 8086. Dac operand-ul surs este parte a instruciuni atunci avem modul de adresare imediat, exemplul tipic este dat de un operand de tip data constant: MOV AL, 015h. Operand-ul de tip imediat poate fi att de tip octet (byte) ct i de tip cuvnt (word). Modul de adresare direct difer de modul de adresare imediat prin faptul c locaia urmtoare instruciunii opcode reine o adres efectiv de memorie, de exemplu: MOV CX, BETA. Aceast adres efectiv este un offset pe 16-bii a unei adrese de memorie a operandul-ui aflat n segmentul de memorie indicat de coninutul registrului DS. Prin combinarea coninutului celor doi regitri se obine adresa fizic a operand-ului n memorie. Adresarea indirect prin registru este similar cu adresarea direct, diferena const n faptul c offset-ul de aceast dat este ntr-un registru pointer sau un registru index din microprocesorul 8086. Registrul pointer poate fi registrul de baz BX sau registrul de baz pointer BP i ca registru index poate fi utilizat registrul index surs SI sau registrul index destinaie DI. Instruciunea MOV AX, [SI], transfer coninutul locaiei de memorie din segmentul curent DS, cu offset-ul dat de coninutul registrului SI, n registrul AX. n modul de adresare bazat adresa fizic a operand-ului este obinut prin adunarea unui deplasament la coninutul registrului de baz BX sau registru pointer de baz BP i combinarea acestui coninut cu coninutul registrului de segment de memorie curent diponibil, DS sau

Microprocesoare i Microcontrolere

199

SS. De exemplu instruciunea: MOV [BX], BETA, AL utilizeaz registru baz BX i un deplasament direct pentru a determina offset-ul operand-ului n segmentul data de memorie, specificat de coninutul registrului DS. Operandul surs astfel adresat va fi transferat n registrul acumulator AL. Dac n locul regitrilor BX sau BP se vor utiliza regitri index pentru determinarea adresei fizice a operand-ului obinem modul de adresare indexat. n exemplul urmtor: MOV AL, ARRAY[SI] notaia ARRAY este un prefix la registrul SI i semnific un deplasament al registrului index. Dac combinm adresarea bazat cu adresarea indexat obinem un nou mod de adresare, adresarea bazat indexat. n instruciunea MOV AH, [BX].BETA [SI] operand-ul surs este accesat utiliznd modul de adresare bazat indexat. Adresa offset de aceast dat este obinut prin nsumarea coninutului registrului BX cu deplasamentul BETA i respectiv coninutul registrului SI. Adresarea ir n cazul microprocesorului 8086 utilizeaz n mod automat registrul surs i destinaie index. Instruciunea MOVS dei nu specific nici un operand n mod explicit pe timpul execuiei va fi utilizat registrul index surs SI i registrul destinaie DI. Pentru adresarea port-ului sunt utilizate n conjuncie dou instruciuni IN i OUT pentru a accesa porturile de intrare respectiv de ieire. De exemplu prin executarea instruciunii: IN AL, 15h registrul AL va fi ncrcat cu coninutul portului de la adresa 15h din spatiul de adrese I/O. Microprocesorul 8086 are un set puternic de instruciuni format din 117 instruciuni de baz. La nivel de cod main aceste instruciuni se expandeaz funcie de operand-ul utilizat i modurilor de adresare disponobile. Setul de instruciuni este divizat ntr-un numr de grupuri de instruciuni cu funcionaliate relativ identic.

Instruciuni de transfer Aceste instruciuni au drep scop de a transfera date ntre regitri microprocesorului 8086 sau ntre regitri i locaiile de memorie destinate stocrii acestor date.
Instruciunea MOV este utilizat pentru a transfera un octet sau un cuvnt de la un operand surs la un operand destinaie. Meaning Move Format MOV dest, src Operation (src) (dest) Flags Affected None

Memonic MOV

200

Setul de Instruciuni al Familiei de Microprocesoare 80X86


Instruciunea XCHG dest, src (exchange) schimb coninutul sursei cu destinaia fr a afecta vreun flag. Instruciunea XLAT/XLATB (translate) modific octeul din registrul Al cu un octet din tabelul utilizator adresat de coninutul registrului BX. Valoarea iniial din registrul AL este un index n tabelul de translatare. Um mod simplu de a transcrie aceast instruciune este: MOV AL, [BX+AL] echivalent cu XLAT Tralslation-Table. Aceast instruciune nu modific nici unul din flag-urile microprocesorului. Instruciunea LEA dest,src (Load Efective Address) calculeaz offset-ul operand-ului surs i l incarc n registrul destinaie. Nu modific flag-urile microprocesorului. Instruciunea LES dest,src (Load Pointer Using ES) transfer patru octei consecutivi de la un operand surs din memorie la o pereche de regitri de 16 bii. Unul din regitri destinaie este specificat de instruciune iar cellat este implicit registrul ES. Aceast instruciune nu modific flag-urile microprocesorului. Instruciunea LDS dest,src (Load Pointer Using DS) este identic cu instruciunea precedent numai c registru implicit de aceast dat este registrul DS. Nu modific flag-urile microprocesorului. Ultimile dou instruciuni simplific ncrcarea unor pointer de tip far din stiv sau tabela vectorilor de ntrerupere.

Instruciuni Aritmetice Cu ajutorul acestor instruciuni microprocesorul 8086 poate realiza operai aritmetice ca: adunare, scdere, nmulire i mprire.
Mnemonic ADD ADC INC AAA DAA Instruciuni de adunare Meaning Addition Add with carry Increment by 1 ASCII adjust for addition Decimal adjust for addition Mnemonic SUB SBB DEC AAS Format ADD dest, src ADC dest, src INC dest AAA DAA Operation (src)+(dest) (dest) (src)+(dest)+(CF) (dest) (dest)+1 (dest) Flags Affected OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF

Instruciuni de scdere Meaning Subtraction Subtract with barrow Decrement by 1 ASCII adjust for subtraction Format SUB dest, src SBB dest, src DEC dest AAS Operation (src)-(dest) (dest) (src)-(dest)-(CF) (dest) (dest)-1 (dest) Flags Affected OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF

Microprocesoare i Microcontrolere
DAS Decimal adjust for subtraction Mnemonic MUL DIV IMUL IDIV AAM AAD CBW CWD DAS

201

OF,SF,ZF,AF,PF,CF

Instruciuni de nmulire i mprire Meaning Multiply (Unsigned) Division (unsigned) Integer Multiply Integer Divide Adjust AL for multiplication Adjust AX for division Convert byte to word Convert word to word Format MUL src DIV src IMUL src IDIV src AAM AAD CBW CWD Operation (AL).src8 (AX) Q(AX)/src8 (AL) R(AX)/src8 (AH) (AL).src8 (AX) Q(AX)/src8 (AL) R(AX)/src8 (AH) Q(AL)/10 (AH) (AH).10+AL (AL) (MSB of AL) (All bits of AH) MSB of AX) (All bits of DX) Flags Affected OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF None NONE

Instruciuni Logice

Instruciunile logice disponibile la microprocesorul 8086 sunt: AND, OR, Exclusive OR i NOT.
Mnemonic AND OR XOR NOT Meaning Logical AND Logical inclusive OR Logical Exclusive -OR Logical NOT Format AND dest, src OR dest, src XOR dest, src NOT dest Operation (src).(dest) (dest) (src)+(dest) (dest) (src) (dest) (dest) (dest) (dest) Flags Affected OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF OF,SF,ZF,AF,PF,CF

202

Setul de Instruciuni al Familiei de Microprocesoare 80X86

Instruciuni de Shift-are Operaiile de baz realizate de aceste instruciuni sunt shift-ul logic i shiftul aritmetic.
SAL/SHL dest, count (Shift Arithmetic Left / Shift Logical Left) shift-eaz operand-ul destinaie cu un numr de bii la stnga (count, pentru 8086 shift-ul disponibil este numai cu un bit) prin inserie de bii zero la dreapta. Flag-ul CF (Carry Flag) conine ultimul bit shift-at n afara operand-ului destinaie. Aceast instruciune afecteaz urmtoarele flag-uri: CF, OP, PF, SF, ZF iar starea flag-ului AF este nedefinit. Aceste instruciuni asigur un mecanism foarte eficient pentru dublarea unui numr. Deoarece nu se face distincie ntre dublarea unui numar cu semn i a unui numr fr semn SAL i SHL sunt dou mnemonici diferite pentru aceeai instruciune. SAR dest, count (Shift Arithmetic Right) shift-eaz operand-ul destinaie cu un numr de bii la dreapta (count, pentru 8086 shift-ul disponibil este numai cu un bit) fr a modifica bit-ul de semn. Flag-ul CF (Carry Flag) conine cel mai puin semnificativ bit shift-at n afara operand-ului destinaie, care dac este setat n "1" arat c numrul nu a fost par. Aceast instruciune afecteaz urmtoarele flag-uri: CF, OP, PF, SF, ZF iar starea flag-ului AF este nedefinit. Acest instruciune asigur un mecanism foarte eficient pentru njumtirea unui numr cu semn. SHR dest, count (Shift Logical Right) ) shift-eaz operand-ul destinaie cu un numr de bii la dreapta (count, pentru 8086 shift-ul disponibil este numai cu un bit) prin inserie de bii zero la stnga. Flag-ul CF (Carry Flag) conine ultimul bit shift-at n afara operand-ului destinaie. Aceast instruciune afecteaz urmtoarele flag-uri: CF, OP, PF, SF, ZF iar starea flag-ului AF este nedefinit.

Instruciuni de Salt Ramificrile ntr-un program sunt realizate prin instruciuni de salt condiionat, acest tip de instruciuni sunt prezentate n tabelul urmtor.
Mnemonic JA JAE JB JBE JC JCXZ JE JG JGE Meaning Jump if Above Jump if Above or Equal Jump if Below Jump if Below or Equal Jump if Carry Jump if CX Zero Jump if Equal Jump if Greater (signed) Jump if Greater or Equal (signed) Jump Condition CF=0 and ZF=0 CF=0 CF=1 CF=1 or ZF=1 CF=1 CX=0 ZF=1 ZF=0 and SF=OF SF=OF

Microprocesoare i Microcontrolere
JL JLE JMP JNA JNAE JNB JNBE JNC JNE JNG JNGE JNL JNLE JNO JNP JNS JNZ JO JP JPE JPO JS JZ Jump if Less (signed) Jump if Less or Equal (signed) Unconditional Jump Jump if Not Above Jump if Not Above or Equal Jump if Not Below Jump if Not Below or Equal Jump if Not Carry Jump if Not Equal Jump if Not Greater (signed) Jump if Not Greater or Equal (signed) Jump if Not Less (signed) Jump if Not Less or Equal (signed) Jump if Not Overflow (signed) Jump if No Parity Jump if Not Signed (signed) Jump if Not Zero Jump if Overflow (signed) Jump if Parity Jump if Parity Even Jump if Parity Odd Jump if Signed (signed) Jump if Zero SF != OF ZF=1 or SF != OF Unconditional CF=1 or ZF=1 CF=1 CF=0 CF=0 and ZF=0 CF=0 ZF=0 ZF=1 or SF != OF SF != OF SF=OF ZF=0 and SF=OF OF=0 PF=0 SF=0 ZF=0 OF=1 PF=1 PF=1 PF=0 SF=1 ZF=1

203

De asemenea n scrierea unui program apar situaii n care unica soluie este un salt necondiionat. JMP target (Unconditional Jump) transfer necondiionat controlul la eticheta
"target". Dac nu este specificat saltul se consider a fi n domeniul relativ de adrese, de la -32768 la 32767. Un salt apropiat (NEAR) sau un salt scurt (SHORT) modific coninutul registrului IP. Un salt ndeprtat (FAR) va modifica att coninutul registrului IP ct

i coninutul registrului CS.

Instruciuni de Rotire Aceste instruciuni pot roti coninutul unui registru intern sau a unei locaii de memorie.
RCL/RCR dest, count (Rotate Through Carry Left / Rotate Through Carry Right) rotete bii din operand-ul destinaie la stnga, respectiv la dreapta cu un numr de bii

204

Setul de Instruciuni al Familiei de Microprocesoare 80X86


definit de "count". Bitul de la un capt este adus n urma rotirii pentru a ocupa pozitia flag-ului CF, iar vechea valoare a flag-ului CF va ocupa poziia vacant n cellat capt. Aceaste instruciuni afecteaz flag-urile CF i OP. ROL/ROR dest, count (Rotate Left / Rotate Right) rotete bii din operand-ul destinaie la stnga, respectiv la dreapta cu un numr de bii definit de "count". Bitul de la un capt este adus n urma rotirii pentru a ocupa poziia vacant n cellat capt. n acelai timp acest bit va ocupa i potiia din flag-ul CF. Aceaste instruciuni afecteaz flag-urile CF i OP.

Instruciuni de Comparare Acest instruciune pote s compare numere pe 8 sau 16 bii.


CMP dest, src (Compare) scade coninutul sursei din coninutul destinaiei i fixeaz flag-urile funcie de acest rezultat fr a modifica coninutul sursei sau destinaiei. Flagurile mofificate sunt: AF, CF, OF, PF, SF, ZF i pot fi testate pentru a verifica ndeplinirea unei condiii ntr-un program.

Instruciuni de Control al Flag-urilor Executarea acestor instruciuni duce la modificarea flag-urilor.


LAHF (Load Register AH From Flags) copiaz bii 0-7 ai registrului de flag-uri n registrul AH, fr a le afecta. Coninutul registrului AH va fi de forma AH:= SF ZF xx AF xx PF xx CF. SHAF (Store AH Register into Flags) transfer bii 0-7 ai registrului AH n registrul de flag-uri. Flagurile transferate sunt: AF; CF, PF, SF, i ZF. CLC (Clear Carry) poziioneaz flag-ul CF n "0". STC (Set Carry) poziioneaz flag-ul CF n "1". CMC (Complement Carry Flag) inverseaz starea flag-ului CF. CLI (Clear Interrupt Flag) dezactiveaz ntreruperea mascabil hardware (INTR, flagul IF are valoarea "0") fr a afecta i ntreruperea NMI sau ntreruperile software. STI (Set Interrupt Flag) activeaz ntreruperea mascabil hardware (INTR) prin setarea flag-ului IF n "1". Dac o ntrerupere mascabil este generat de un dispozitiv hardware trebuie s introducem n program o secven EOI (End of Interrupt) pentru a activa o alt ntrerupere de aceei prioritate sau de prioritate mai sczut.

Microprocesoare i Microcontrolere Instruciuni pentru Subrutine i controlul Subrutinelor

205

Nu de puine ori programul principal trebuie s execute o funcie care este definit printr-o subrutin. Pentru a executa aceasta funcie se face un apel la subrutina care o definete, aa c programul principal trebuie s transfere controlul microprocesorului la nceputul acestei subrutine. Executarea programului va continua cu subrutina apelat i n final va trebui s se ntoarc n programul principal la istruciunea urmtoare celei care a realizat apelul. Dei instruciunile de lucru cu stiva pot fi utilizate ori de cte ori este nevoie ntr-un program, ele sunt prezentate n acest grup deoarece utilizarea lor n scrierea unor aplicaii bine structurate implic folosirea frecvent a acestora n cadrul subrutinelor.
CALL destination (Procedure Call) pune coninutul registrului IP (care n acest moment al execuiei instruciunii CALL conine deja adresa urmtoarei instruciuni, respectiv coninutul registrului CS pentru CALL FAR) pe stiv i ncarc registrul IP (respectiv CS) cu adresa unde ncepe subrutina. Execuia codului continu cu instruciunea de la adresa CS:IP. Execuia acestei instruciuni nu modific flag-urile. INT n (Interrupt) asigur o ntrerupere software (ntrerupere intern), procednd ca la recunoaterea unei ntreruperi hardware de ctre microprocesor. De aceast dat tipul instruciuni este specificat n instruciune (n), n loc de a fi dat de un dispozitiv extern. Este salvat pe stiv adresa CS:IP a instruciunii urmtoare i n plus registrul de flaguri. Noua adres (CS:IP) este obinut din tabelul vectorilor de ntrerupere folosind ca baz de calcul tipul ntreruperii. RET nBytes / RETF nBytes / RETN nBytes (Return From Procedure) este operaia invers apelului de subrutin, readucnd din stiv valoarea lui IP (respectiv CS) avut la momentul apelrii subrutinei. Dac n stiv avem un numr de cuvinte ncrcae peste cuvntul ce conine adresa salvat de instruciunea CALL atunci n mod opional istruciunea RET poate fi urmat de un operand imediat a crui coninut se adun la coninutul registrului SP. IRET (Interrupt Return) plasat la sfritul unei proceduri de ntrerupere are ca efect refacerea valoriilor CS:IP salvate anterior pe stiv. Spre deosebire de returul intersegment (far) aceast instruciune reface i registrul de flag-uri. PUSH src (Push Word into Stack) salveaz din operand-ul surs un cuvnt n stiv (SS:SP) i decrementeaz registrul SP cu doi pentru ca registrul SP s conin offset-ul urmtoarei locaii n care poate fi salvat un cuvnt. Instruciunile de acest tip nu modific flag-urile. POP dest (Pop a Word from the Stack) extrage un cuvnt din stiv (SS:SP) n operandul destinaie i incrementeaz registrul SP cu doi pentru ca registrul SP s conin offset-ul urmtorului cuvnt ce poate fi extras din stiv (vrful stivei). Cu excepia instruciuni POPF (extrage din stiv un cuvnt care va fi ncrcat n registrul de flag-uri) celelalte instruciuni de acest tip nu modific flag-urile.

206

Setul de Instruciuni al Familiei de Microprocesoare 80X86

Instruciuni de Ciclare Instruciunile de ciclare permite programatorului realizarea cu uurin a unor bucle n program.
LOOP label ( Loop until Count Complete, Decrement CX and Loop if CX Not Zero) decrementeaz coninutul registrului CX cu 1 i transfer controlul la operand-ul "label" (etichet) dac coninutul registrului CX nu este zero. Operand-ul "label" trebuie s fie n domeniul de adrese de la -128 pn la 127 octei, domeniu raportat la adresa urmtoarei instruciuni. LOOPE/LOOPZ label (Loop While Equal / Loop While Zero) decrementeaz coninutul registrului CX cu 1 (fr a modifica flag-urile) i transfer controlul la operand-ul "label" (etichet) dac coninutul registrului CX nu este zero i ZF = 1. Operand-ul "label" trebuie s fie n domeniul de adrese de la -128 pn la 127 octei, domeniu raportat la adresa urmtoarei instruciuni. LOOPNZ/LOOPNE label (Loop While Not Zero / Loop While Not Equal) decrementeaz coninutul registrului CX cu 1 i transfer controlul la operand-ul "label" (etichet) dac coninutul registrului CX nu este zero i ZF = 0. Operand-ul "label" trebuie s fie n domeniul de adrese de la -128 pn la 127 octei, domeniu raportat la adresa urmtoarei instruciuni.

Instruciuni cu iruri Prin intermediul acestor instruciuni pot fi uor executate operaile cu iruri. Aceste instruciuni sunt printre cele mai complexe i utilizarea lor este nu de puine ori evitat. Lucrul eficient cu un numr mare de date nu poate fi realizat fr utilizarea intensiv a acestui tip de instruciuni.
MOVS dest, src (Move Data from String to String) realizeaz transferul datelor dintr-un ir, cu offset-ul n registru SI, ntr-un ir obligatoriu n extrasegmentul de date (ES) cu offset-ul n DI. De obicei operandul surs se afl n segmentul de date (DS). Dup executare instruciuni regitri index sunt incrementai sau decrementai (cu 1, 2, 4 pentru MOVSB, MOVSW, MOVSD) funcie de starea flag-ului de direcie DF. Numrul de elemente ale irului este specificat de coninutul registrului CX. Execuia acestor instruciuni nu modific flag-urile microprocesorului. CMPS dest, src (Compare String Operands) compar dou secvene de octei/cuvnte/dublu-cuvnte (CMPSB, CMPSW, CMPSD) i anume coninutul adreselor de memorie adresate de coninutul registrului SI, respectiv DI. Numrul de elemente de comparat este dat de coninutul registrului CX, iar regitri index sunt incrementai sau decrementai (1, 2, 4) funcie de starea flag-ului DF. Flag-urile modificate sunt: AF, CF, OF, PF, SF, ZF. SCAS string (Scan String) execut operaia de scanare a elementelor unui ir octei/cuvnte/dublu-cuvnte (SCASB, SCASW, SCASD) i anume coninutul

Microprocesoare i Microcontrolere

207

adreselor de memorie adresate de coninutul registrului DI, comparaia fcndu-se n raport cu coninutul registrului AL/AX/EAX. Numrul de elemente de comparat este dat de coninutul registrului CX, iar registrul index este incrementat sau decrementat (1, 2, 4) funcie de starea flag-ului DF. Nu se depune nici un rezultat dar sunt afectate flagurile: AF, CF, OF, PF, SF, ZF. LODS src (Load String Element) realizeaz operaia de ncrcare a octetului/cuvntului/dublu-cuvntului (LODSB, LODSW, LODSD) a crui offset n memorie este dat de coninutul registrului SI, n AL/AX/EAX. Numrul de elemente de transferat este dat de coninutul registrului CX, iar registrul index este incrementat sau decrementat (1, 2, 4) funcie de starea flag-ului DF. STOS dest (Store String) realizeaz operaia de stocare a octetului/cuvntului/dublucuvntului (STOSB, STOSW, STOSD) din registrul AL/AX/EAX n locaia de memorie a crui offset este dat de coninutul registrului DI. Numrul de elemente de transferat este dat de coninutul registrului CX, iar registrul index este incrementat sau decrementat (1, 2, 4) funcie de starea flag-ului DF.

Instruciuni cu Porturi Lucrul cu porturile este mult simplificat prin utilizarea unui spatiu de adresare saparat de cel de memorie. n evoluia microprocesorului lipsa de eficien n transferul de date prin porturi a dus la diversificarea acestor instruciuni n sensul accesrii porturilor prin operaii de trasfer de tip ir.
IN AL, port / IN AL, DX (Input) citete un octet de la operand-ul surs care poate fi specificat n mod direct printr-un octet pentru un port cu adresa mai mic sau egal cu FFh. Pentru porturi cu adresa n domeniul de la 100h pn la FFFFh este obligatorie utilizarea registrului DX, acesta va conine adresa curent a portului (indirect). OUT port, AL / OUT DX, AL (Output) scrie coninutul acumulatorului AL la un port de ieire specificat direct sau indirect prin registrul DX.

Microprocesorul 80286 Microprocesorul Intel 80286 este o extensie a versiuni de baz 8086, principalele facilitii introduse de aceast versiune sunt legate de modul de exploatare a memoriei. ncepnd cu aceast versiune au fost introduse capabiliti de protejare a memoriei cu scopul de a susine sisteme de operare multiuser/multitasking (primele versiuni Windows, practic necunoscute marelui public). Acest microporocesor este capabil s adreseze un spaiu fizic de memorie de 16MB i 1 GB de memorie virtual per task. Microprocesorul 80286 are dou moduri de operare - modul de adresare real i modul de adresare virtual protejat. n modul de

208

Setul de Instruciuni al Familiei de Microprocesoare 80X86

operare real un microprocesor 80286 nu este compatibil la nivel de cod obiect cu 8086 dar este compatibil la nivel de cod surs. De asemenea sistemul de operare MS-DOS nu a utilizat modul de adresare a memoriei virtual protejat.

Setul de Instruciuni al Microprocesorului 80286 Microprocesorul 80286 poate executa tot setul de instruciuni al microprocesorului 8086, precum i urmtoarele instruciuni cu rol de suport al sistemului de operare.
ARPL (Adjusted Requested Privilege Level of Selector) CLTS (Clear Task Switched Flag) LAR (Load Access Rights) LGDT (Load Global Descriptor Table) LIDT (Load Interrupt Descriptor Table) LMSW (Load Machine Status Word) LSL (Load Segment Limit) LSS (Load Pointer Using SS) LTR (Load Task Register) SGDT (Store Global Descriptor Table) SIDT (Store Interrupt Descriptor Table) STR (Store Task Register) VERR (Verify Read Usage: VERR src) VERW (Verify Write)

Microprocesorul 80386 Microprocesorul 80386 i cele de dup el au regitri de 32 de bii. Toi cei opt regitri de 16 bii au echivaleni de 32 de bii. Acetia sunt: EAX, ABX, ECX, EDX, ESI, EDI, EBP, i ESP. Dac microprocesorul de pe placa de baz este un 80386 sau unul mai recent aceti registri pot fi utilizai ca operand cu unele instruciuni. Odat cu introducerea microprocesorului 80386 au fost generalizate modurile de adresare a memoriei. Spre deosebire de 8086 care poate utiliza ca regitri de baz doar regitri BX i BP iar ca regitri index doar regitri SI i DI, microprocesorul 80386 permite utilizarea oricrui registru de uz general de 32 de bii ca registru baz sau index. De asemenea odat cu microprocesorul 80386 au fost introduse noi moduri de adresare scalat i indexat a memoriei simplificnd astfel

Microprocesoare i Microcontrolere

209

accesul la date de tip array. Pe lng creterea la 32 de bii a dimensiuni regitrilor probabil noile moduri de adresare a memoriei sunt cele mai importante nbuntiri ale microprocesorului n acest stadiu de dezvoltare. La acest nivel de dezvoltare microprocesoarele Intel au avut suficient putere i facilii software pentru a suporta un sistem de operare multi-user/multitasking de uz profesional cum ar fi de exemplu UNIX (LINUX).

Setul de Instruciuni al Microprocesorului 80386 Setul de instruciuni amicroprocesorului 80386 include setul de instruciuni a microprocesorului 80286 i adaug urmtoarele instruciuni.
BST (Bit Scan Forward) BSR (Bit Scan Reverse) BT (Bit Test) BTC (Bit Test with Compliment) BTR (Bit Test with Reset) BTS ( Bit Test and Set) CD0 (Convert Double to Quad ) CWDE (Convert Word to Extended Doubleword ) LGS (Load Pointer Using GS) LSS (Load Pointer Using SS ) MOVSX ( Move with Sign Extend ) MOVZX ( Move with Zero Extend ) SETAE/SETNB (Set if Above or Equal / Set if Not Below ) SETB/SETNAE (Set if Below / Set if Not Above or Equal ) SETBE/SETNA (Set if Below or Equal / Set if Not Above) SETE/SETZ (Set if Equal / Set if Zero) SETNNE/SETNZ ( Set if Not Equal / Set if Not Zero ) SETL/SETNGE (Set if Less / Set if Not Greater or Equal) SETGE/SETNL (Set if Greater or Equal / Set if Not Less) SETLE/SETNG (Set if Less or Equal / Set if Not greater or Equal) SETG/SETNLE (Set if Greater / Set if Not Less or Equal ) SETS (Set if Signed) SETNS (Set if Not Signed) SETC (Set if Carry) SETNC (Set if Not Carry ) SETTO (Set if Overflow) SETNO (Set if Not Overflow) SETP/SETPE (Set if Parity / Set if Parity Even) SETNP/SETPO (Set if No Parity / Set if Parity Odd) SHLD/SHRD (Double Precision Shift)

210

Setul de Instruciuni al Familiei de Microprocesoare 80X86

Microprocesorul 80486 Odat cu versiunea 80486 a microprocesorului, Intel a lansat i coprocesorul RISC i860, fiecare coninnd mai mult de 1 milion de tranzistori. Microprocesorul RISC are o unitate aritmetic i logic de 32 de bii (aceast unitate a microprocesorului este responsabil de execuia unor operaii cum ar fi adunarea sau scderea) dublat de o unitate n virgul flotant pe 64 de bii. Toate acestea au fost oferite iniial la o frecven de ceas de 33 Mhz. Dei microprocesorul 80486 a rmas similar cu 80386 setul de instruciuni a fost optimizat iar adugarea unui cache intern precum i nglobarea n acelai chip pentru prima dat a coprocesorului n virgul flotant a dus la dublarea performantelor far o cretere a frecvenei de tact.

Setul de Instruciuni al Microprocesorului 80486 Setul de instruciuni ale microprocesorului 80486 include setul de instruciuni ale microprocesorului 80386 la care s-au mai adugat urmtoarele:
BSWAP (Byte Swap) INVD ( Invalidate Cache) INVLPG (Invalidate Translation Look-Aside Buffer Entry) WBINVD (Write-Back and Invalidate Cache)

Microprocesorul PENTIUM PENTIUM este un microprocesor de 32 de bii. Setul de instruciuni i modurile de adresare sunt aproape similare cu ale microprocesorului 80486. ncepnd cu versiunea MMX a microprocesorului au fost introduse o serie de instruciuni noi care ofer suport pentru aplicaiile multimedia. Evoluia microprocesorului este de natur hardware i const ntr-o diversificare i mai eficient utilizare a resurselor interne susinut de o viteza de rulare a instruciunilor din ce n ce mai mare.

Microprocesoare i Microcontrolere

211

B. Setul de Instruciuni al Microcontrolerului 68HC11

Instruciunile microcontrolerului 68HC11 prezentate n continuare sunt organizate n urmtoatele categorii:


load, store, i instruciuni de transfer instructiuni aritmetice operaii logice instruciuni de manipulare pe bit i testare instruciuni de shift-are i rotire istruciuni cu registri index i de stiv instruciuni de salt

Tabele din paginile urmtoare sunt preluate din Motorola's M68HC11 Reference Manual.

Load, Store, i Instruciuni de Transfer

Coninutul acumulatorilor A, B, i D poate fi ncrcat (load) sau stocat (stored) n memorie. Coninutul acumulatorilor A, B poate fi transferat napoi i nainte.

212

Setul de Instruciuni al Microcontrolerului 68HC11


Coninutul acumulatorilor A, B poate fi transferat n i din stiv. Coninutul registrului acumulator D (double-precision, A concatenat cu B) poate fi schimbat cu coninutul regitrilor index X iY.

Instruciuni Aritmetice

Instruciunile aritmetice de baz includ adunarea, scderea, incrementare, decrementare i comparare, cele mai multe instruciuni sunt n simpl precizie.

Not: Nu sunt posibile intruciuni aritmetice memorie-memorie, un operant trebuie s fie de tip registru.

Microprocesoare i Microcontrolere Opreraii Logice

213

Coninutul acumulatorului A poate fi utilizat pentru operaii logice (AND, OR, sau exclusive-OR) cu memoria. Coninutul acumulatorilor A, B, i locaile de memorie specificate pot fi complementate logic (bit-wise).

Instruciuni de Manipulare pe Bit i Testare

Bii individuali din memorie pot fi setai sau resetai, sau pot fi fcute salturi
condiionate de valoarea acestora.

214

Setul de Instruciuni al Microcontrolerului 68HC11

Instruciuni de Shift-are i Rotire

Coninutul acumulatorilor A, B, D precum i coninutul unor locaii de memorie specificate poate fi shif-at stnga sau dreapta cu un bit att aritmetic ct i logic.

Coninutul acumulatorilor A, B, D precum i coninutul unor locaii de memorie


specificate poate fi rotit stnga sau dreapta cu un bit cu transfer prin bitul C din registrul CCR (Condition Code Register).

Not: Nu sunt diferene ntre shift-ul logic i aritmetic spre stnga.

Microprocesoare i Microcontrolere Instruciuni cu Registri Index i de Stiv

215

Coninutul regitrilor index X, Y, poate fi ncrcat, stocat sau comparat cu memoria i poate fi salvat sau ncrcat n/din stiv. Coninutul registrilor index X, Y, i al registrului de siv SP poate fi incrementat sau decrementat. Coninutul registrilor index X, Y, poate fi transferat n/din SP sau schimbat cu registrul dublu D.

216

Setul de Instruciuni al Microcontrolerului 68HC11

Instruciuni de Salt Instruciunile de salt pot fi necondiionate sau condiionate de unul sau mai muli bii din registru CCR (Condition Code Register):
Un salt simplu este condiionat numai de un bit de condiie. Un salt comparat este condiionat de instruciunea precedenta de scdere sau comparare i de regul este dependent de mai mult dect un singur bit din registrul CCR.

Microprocesoare i Microcontrolere

217

C. Setul de Instruciuni al Microcontrolerului PIC 16F84

n tabelul de mai jos este rezumat setul de instruciuni al microcrocontrolerului PIC16F84 avnd drept baz specificaia corporaiei MicroChip Tehnology.

Note: - Cnd un registru I/O este modificat ca o funcie de sine nsui (de exemplu, MOVF PORTB, 1), valoarea utilizat va fi aceea valoare prezent pe pini. De exemplu, dac data lach este '1' pentru un pin configurat ca input i acest pin este forat n '0' de un dispozitiv exterior, data va fi rescris cu zero. - Dac o instruciune va fi executat n registrul TMR0 (i, unde este aplicabil, d = 1), prescalerul va fi resetat dac este referit de TMR0. - Dac registrul PC (Program Counter) este modificat sau un test condiional este adevrat, instruciunea va fi executat pe timpul a dou perioade de ceas. Pe timpul celei de a doua perioade va fi executat o instruciune NOP.

218

Setul de Instruciuni al Microcontrolerului PIC 16F84