Ú-5  Styk mikropočítača s prostredím

 
 
 µ Generovanie časových intervalov
   q Generovanie oneskorenia programovo
   q Generovanie impulzov s použitím timera
     q Generovanie tónu na reproduktor programovo
     q Generovanie tónu na reproduktor s použitím timera
     q Meranie  časových intervalov s pomocou služieb BIOS a DOS
     q Meranie  časových intervalov pomocou timera
   q Kontrola funkcie timera pomocou osciloskopu


µ Generovanie časových intervalov

 
1.  Generovanie oneskorenia programovo

q Programovo je najjednoduchšie generovať kratšie intervaly do 250ms pomocou oneskorovacej slučky s podmieneným skokom JZ, JNZ a pod. alebo pomocou inštrukcie LOOP, ktoré sú založené na testovaní obsahu zvoleného registra, ktorý sa po prechode cez sľučku dekrementuje. Ako počitadlo sa najčastejšie (a v mnohých inštrukciach impicitne) používa register CX.

Napríklad inštrukcia LOOP v nasledujúcom prípade vykonáva prechod cez sľučku dovtedy až sa nedosiahne nulový obsah počítadla CX -> 0. Pre oneskorenie v trvaní pribliážne 250 ms treba zadať v počítači PP06 CX=0FFFFH. (V iných typoch počítačov s odlišnou taktovacou frekvenciou mikroprocesora bude oneskorenie odlišné od uvedeného).
 
 
Loop_Value 
Equ 0FFFFH
    Mov cx,  LOOP_VALUE
  Here: Loop Here

q Na programové generovanie dlhšich intervalov ( od 250 ms do 1s ) možno použiť start - stop metódu, podobne ako pri meraní časového intervalu pomocou stopiek. Začiatok merania určuje impulz - Štart z počítača a koniec merania impulz - Stop z vonkajšieho zariadenia, pripojeného k vybranému bitu určitého portu. Pri testovaní stavu tohto bitu sa používa operácia logického súčinu - AND obsahu registra portu a vhodnej masky - MASKBIT, pomocou ktorej sa vyčlení zo stavového slova portu len jediný bit, ktorý je predmetom záujmu (v nasledujúcom demonštračnom programe je použitá modifikácia operácie logického súčinu - Test, ktorá po vykonaní logického súčinu ponechá pôvodný, operaciou AND nepozmenený obsah registra al ).

Napríklad ak je známe trvanie jedného prechodu cez oneskorovaciu sľučku ( v naledujúcom príklade trvajúci 10-20ms ) možno na základe obsahu počitadla prechodov cez slučku CX po domeraní určiť trvanie celkového oneskorenia (v jednotkách trvania jedného prechodu cez slučku, teda v príklade v jednotke trvania okolo 10-20ms).
 
 
MASKBIT 
Equ 01H ;zamaskuje všetko okrem bitu D0
    Mov dx, PORT  
    Mov cx, 0  
  Here: In al, dx ;číta stav PORTu
    Test al, MASKBIT ; maskovanie vybraného bitu
    loopne Here  
  Done:    ;=>(cx)= pocet iterácii


2. Generovanie impulzov s použitím timera

Programovateľný obvod ma generovanie časových intervalov - PIT (Programmable Interval Timer resp. skrátene timer, časovací obvod, časovač) typ 8253, resp typ 8254 obsahuje v sebe 3 počítadlá SC_0 až SC_2 (obr. 5-1 a obr. 5-2), ktorých spôsob činnosti sa ovláda pomocou uloženia kódu riadiaceho slova CWRTW do riadiaceho registra CWRT. Počítadla SC sú 16 bitové a možno z nich čítať, resp. zapisovať do nich oddelene len dolný bajt (LSB) zo 16 bitového slova alebo len horný bajt (MSB), poprípade celé 16 bitové slovo v poradí najprv LSB a potom MSB. Okrem tohto spôsobu čítania obsahu počitadiel v kľudovom stave možno snímať aj obsah bežiaceho počítadla, pomocou zachytenia jeho aktuálneho stavu v určitom okamihu. V osobných počítačoch sa používa minimálne jeden takýto obvod timera na generovanie signálov pre hodiny reálneho času, na generovanie impulzov pre osviežovanie obsahu dynamických pamätí DRAM a tiež na generovanie zvukového signálu.

Počítadlá timera v IBM PC sú obvykle alokované na adresách I/O obvodov :
 
  SC0 - 40H, SC1 - 41H, SC2 - 42H  CWRT - 43H

(užívateľsky môžu byť samozrejme alokované aj na inej adrese I/O, napr. v príklade tim2.asm)
 

Obr. 5-1. Časovač PIT 8253 v systéme PC.

 
Obr. 5-2.. Vnútorná štruktúra časovača PIT 8253.









u Ilustrácia činnosti PIT - 8253 v rôznych módoch
 
Obr. 5-3. Ilustrácia činnosti PIT - 8253 v rôznych módoch. (CLK - vstupný signál, GATE - vonkajší hradlovací signál, OUT - výstup počítadla.)

 

Z 6 možných módov (obr. 5-3) sa v osobných počítačoch využívajú štandardne len 3 a to:

Ü Mód 0 - na generovanie žiadosti o prerušenie IRQ. Vyvolané prerušenie a obslužná subrutina zabezpečujú každých 55 ms časový signál pre hodiny reálneho času. Timer v móde 0 po zápise prevoľby (ak GATE=1) sa dekrementuje a po dopočítaní do 0 sa nastaví na úroveň "H", čo je podnetom pre vyvolanie prerušenia . Na základe tohto časového signálu sa 18,2 krát za sekundu zvyšuje obsah registrov, z ktorých sa určuje reálny čas.

Ü Mód 2 - počítadlo s deliacim pomerom n (=> timer po nastavení nepretržite generuje impulzy o trvaní taktu CKL s frekvenciou závislou na deliacom pomere n). Napríklad počítadlo SC_1 sa v PC XT používa ako refresh obsahu dynamických pamätí DRAM (=> každých 15ms sa v móde 2 generuje osviežovací impulz).

Ü Mód 3 - generátor impulzov obdlžnikového tvaru. Ich trvanie a frekvencia závisí od deliaceho pomeru n. Napríklad v programoch na generovanie tónu "beep"- bfig81b.asm.

q Formát riadiaceho slova CWRTW má tvar:
 
D7 D6 D5 D4 D3 D2 D1 D0
SC1 SC0 RW1 RW0 M2 M1 M0 BIN/BCD

 
SC1, SC0 => binárny kód počitadla ktorého mód sa nastavuje. Napríklad:
  00B pre SC0,.
  10B pre SC2.
  11B nie je zadefinovaný
RW1, RW0 => 01B - číta / zapisuje sa len LSB
  10B - číta / zapisuje sa len MSB 
  11B - číta / zapisuje oba bajty v poradí LSB a MSB
  00B - zachytenie stavu za chodu
M2, M1, M0 => binárny kód módu --> spôsobu činnosti
BIN / BCD => 0 - počítadlo v binárnom kóde
BIN / BCD => 1 - počítadlo v kóde BCD.


 
3. Generovanie tónu na reproduktor v PC

V PC pre demonštračné účely je vhodné počítadlo SC_2 (obr. 5-4), ktorého vstup CLK je pripojený na impulzy s frekvenciou = 1,19 MHz. Výstup z počítadla SC_2 cez hradlo a zosilňovač je pripojený k reproduktoru. Možno ho teda blokovať a uvoľňovať pomocou bitu PB1 portu na adrese 61H. Pritom treba tak postupovať, aby sa stav ostatných bitov PB nemenil, resp. na konci obnoviť pôvodný stav. Kvôli úplnosti popisu k obrázku treba ešte uviesť, že činnosť počítadla SC_2 možno ešte blokovať aj pomocou bitu PB0, pripojeného na hradlovací vstup GATE_2 počitadla SC_2. Výstupné impulzy z počitadla SC_2 sú prítomné pre účely testovania na vstupe PC_5, resp.hradlovaný na vstupe PC_6 portu PC, ktorého adresa je 62H.
 
Obr. 5-4. Štandardné zpojenie timera SC#2 v PC-XTna generovanie tónov.

Pomocou uvedeného zapojenia možno generovať tón na pripojený reproduktor 2 rôznymi spôsobmi:

  • programovo na základe vhodného oneskorenia (napr. tón - Bfig_8-1a.asm);
  • s použitím timera (napr. tón - Bfig_8-1b.asm a melódiu - pgn151.asm).


 
q 3a. Generovanie tónu programovo na základe  oneskorenia

Pomocou postupného generovania úrovne "H" a úrovne "L" na výstupe PB1 s vhodným oneskorením, určujúcim frekvenciu tónu. Činnosť počitadla SC_2 je pritom zablokovaná prítomnosťou úrovne PB0=“L” na jeho hradlovacom vstupe GATE_2. Aby sa zachoval pôvodný stav na ostatných bitoch portu PB treba, aby sa po zistení aktuálneho stavu bitov portu PB pomocou vhodnej masky menil len stav výstupu PB1. Vhodnou maskou splňujúcou ešte aj podmienlu na zablokovanie PB0 je súčinová AND maska MSK1 =1111 1110 = 0FEH uvoľňuj[ca výstup PB1 a súčinová AND maska MSK0 = 1111 1100 = 0FCH blokujúca výstup PB1 a PB0.

Bfig_8-1.asm -Generovanie tónu pomocou zmien H - L

Príklad generovania tónu na vstavanom reproduktore počítača, pripojenom cez hradlo k bitu 1 portu PB, na adrese 61H. Samotnému programu musí predchádzať úschova doteraz nastavených HW bitov portov 61H a 62H počítača a ich obnova po skončení procedúry.

  • Prvá demoprocedúra je zložená na generovaní obdlžnikovách impulzov so striedou 1 pomocou striedavého zasielania 1 a 0 na výstup PB1 s oneskorením, ktorým je určená frekvencia tónu. Trvanie tónu je určené počtom opakovaných volaní procedúry, ktorou sa generuje tón.
  • Druhá demoprocedúra ( prakticky zhodna s Beep.asm PC PP06) používa na generovanie tónu timer 8253 v móde 3 . Dĺžka tónu je určená čakacou sľučkou , určenou obsahom registra CX.
V prípade, že inicializácia portov bola už vykonaná po zapnutí počítača ( Port PB out a Port PA a PC in ) bude nasledujúca procedúra generovať tón o trvaní určenom obsahom registra CX a frekvencii určenej trvanim vloženého oneskorenia ( subrutina Onesk ) medzi generovaním stavu “H” a “L”. Frekvencia tónu bude závisieť od rýchlosti počítača =>bude napríklad iná v TURBO móde počítača).
 
 Bfig8-1a.asm.   ;-----------------------------------------
  Mov cx, 0500h ;dľžka tónu 1
  In al, 61h ;Zistenie statusu portu
  Mov bh, al ;uschova nastavenia s PB=0
  and al, 0fdh  ;Nastaveie PB0=0, PB1=0
  out 61h, al   
direct: or al, 00000010B  .;Nastavenie PB1=1
  out 61h, al  ;1 na reproduktor
  call onesk  ;oneskorenie
  and al, 11111101b  .;FDH => PB1=0 na reproduktor
  out 61h, al  
  call onesk  
  Loop direct  
  Mov al, bh  ;Obnova statusu pôvodneho PB
  Out 61h, al  
  Ret  
Onesk 
Push cx  ;frekvencia tonu
  Mov cx, 0500h  
oo: Loop oo  
  pop cx  
  ret  
Onesk 
endp  
    ;----------------------------------------


q 3b. Generovanie tónu s použitím timera

Pritom treba nastaviť počitadlo SC_3 do módu_3. Potom obdlžnikové impulzy z výstupu počitadla SC_2 budú postupovať na reproduktor vtedy, ak bude bit PB1 = 1 a PB0 = 1 Preto je v nasledujúcej demonštračnej procedúre inštrukcia OR AL, 03H Počítadlo SC_2 sa nainicializuje pomocou riadiaceho slova 10/11/011/0 = B6H a kódom 533H = 1333D tak, aby generovalo impulzy so striedou = 1 a frekvenciou 1 kHz ( v prípade počítača PP06 ) a trvaní ~ 0,5 s , dané (CX) . Na rozdiel od predchádzajúcej procedúry sa pri preputí počítača do režimu TURBO nezmení frekvencia generovaných impulzov, zmení sa len trvanie, lebo to je závislé od rýchlosti počítača.

Bfig8-1b.asm - Generovanie tónu pomocou ovladania počitadla SC2 v obvode časovača typu 8253.
 
    ;-----------------------------------------------
Speaker 
proc far  
  MOV AL, 0B6h  ;Nastavenie počitadla 2
  OUT 43h, AL  ;do CWRT
  MOV AX, 1333  ;533h=1333d pre 1 kHz
  OUT 42h, AL  ;do SC2-najprv LSB
  MOV AL, AH   
  OUT 42h, AL  ;potom MSB
  IN AL, 61h  ;Odblokovanie portu 61h
  MOV AH, AL  ;úschova statusu 61h
  OR AL, 03h  ;t.jPB1=1,PB0=1 =>11=3h
  OUT 61h, AL   
  SUB CX, CX  ;max dľžka tónu 0 =>ffffh
sl: LOOP sl ;Čakacia sľučka generovania tonu
  MOV AL, AH ;Obnova statusu 61h
  OUT 61h, AL   
  RET  
speaker 
Endp  

u Pospájanie tónov na melódiu

Tento princip definovania frekvencie impulzov pomocou počitadla timera a trvania tónu pomocou dekrementovaného obsahu registra možno použiť pri generovaní rôznych melódii. Melódiu treba zadefinovať ako skupinu dát pomocou postupností dvojíc slov: frekvencia, dlžka. Pretože dlžka tónu závisí od počtu prechodov cez určitú programovú sľučku bude mať melódia iný rytmus na rôznych počítačoch !
 

Pgn151.asm - Výstup melodie "Mary has a little lamb" na reproduktor.

Príklad procedúry, ktorá zahrá určitú melódiu, takty ktoréj sú uložené v pamäti tabuľky frekvencii M_FREQ (prístup cez DS:SI, s tým, že posledný údaj v tabuľke je marker 0FFFH) a tabuľky trvaní tónov M_TIME (prístup cez DS:BP). Táto procedúra vystupuje v úlohe hlavného programu (na konci End = Mary_Proc udáva začiatok procedúry) a k svojej činnosti potrebije subrutiny Play (Pgn151a.asm) a Sound (Pgn151b.asm)
 

Procedúra Mary_Proc - hlavný program

Procedúra Mary_Proc, tvoriaca hlavný program na generovanie taktov melodie uloženej v pamäti ako tabuľka frekvencii - M_FREQ (zakončena 0FFFH) a dlžok tónov - M_TIME. Celý program na zahratie melódie pozostáva z 3 častí:

  • z hlavného programu pgn151,
  • subrutiny play - pgn151a,
  • subrutiny sound - pgn151b,
ktoré treba po preložení do objektívneho kódu spolu z hlavným programom zlinkovať.
 
   ;hlavný program pgn151.asm  ----- procedúra Mary_Proc ---------
  EXTRN PLAY:FAR  
 Stackseg 
Segment para stack "stack"  
  Db 64 dup ("STACK")  ;zaplni stack ;64 * "STACK"
Stackseg 
ends  
MARY_DATA 
segment para "data"  
  M_FREQ dw  330,294,262,294,3 DUP(330) ;takt 1-2
  Dw 3 DUP(294),330,392,392 ;takt 3-4
  Dw 330,294,262,294,4 DUP(330) ;takt 5-6
  Dw 294,294,330,294,262,0FFFH ;takt 7-8
  M_TIME dW 6 DUP(25),50 ;takt 1-2
  dW  2 DUP(25,25,50) ;takt 3-4
  dW  12 DUP(25),100 ;takt 5-8
 MARY_DATA 
ENDS  
 MARY_CODE 
segment para "code"  
 MARY_PROC 
PROC FAR  
  Assume ds:MARY_DATA, cs:MARY_CODE,ss:stackseg
  PUSH DS  ;Úschova kvôli ret far
  SUB AX, AX  
  PUSH AX ;uschova CS a IP
  mov ax, seg MARY_DATA ;inicial DS
  mov ds, ax  
  lea si, M_FREQ ;ukaz na tab freq
  lea bp, ds: M_TIME ;ukaz na tab dľžka
  CALL PLAY  
  mov ah, 4ch  
  int 21h  
  RET  
 MARY_PROC 
ENDP  
 MARY_CODE 
ENDS  
  END MARY_PROC  
    ;----------------------------------------

Pgn151a.asm- Subrutina Play

Subrutina Play, zabezpečujúca výber spravnych frekvencii a dľžok tonu z príslušných tabuliek M_FREQ a M_TIME, ktoré zodpovedajú príslušnej melódii.

Pgn151a.asm - Subrutina Play zabezpečujúca výber správnych frekvencii a trvaní tónov pre zahratie melodie podľa tabulky uloženej v pamäti pomocou DS:SI pre frekvencie (zakončená markerom 0fffH) a pomocou DS:BP pre trvanie tónu.
 
  Vstup: DS:SI - začiatok tabuľky frekvencii zakončenej 0FFFH
    DS:BP - začiatok tabuľky dľžky tónu

 
    ;---- Pgn151b-generovanie tónu --
  EXTRN sound:far  
 ccode 
segment para public  "code"
  assume cs:ccode  
 play 
proc far  
  public play ; používa ju pgn151
  push bx ;Úschova
  push di  
  push si  
  push bp  
 freq: mov di, [si] ;uložit frekvencie
  cmp di, 0fffh ;koniec melodie?
  je end_play  
  mov bx, ds:[bp] ;Uložiť dľžku tónu
  call sound ;Generovan tónu
  add si,2 ;posun v tab o 2
  add bp,2  
  jnz freq  
 end_play:    
  pop bp  
  pop si  
  pop di  
  pop bx  
  Ret  
 play 
endp  
 code 
ends  
  End  

Pgn151b.asm- Subrutina Sound na generovanie tónu

Procedúra Sound , ktorá sa používa na generovanie tónu o frekvencii zadanej (DI) a trvaním zadaným (BX). Frekvencia v tabuľkei M_FREQ je zadaná v Hz:
 
  Tón/Hz C Cis D Dis E F
  1 okt 130,8 138,6 146,8 155,6 164,8 174,6
  2 okt 261,7 247,2 293,7 311,1 329,6 349,2
   
  Tón/Hz Fis G Gis A Ais H
  1 okt 185 196 207,7 220 233 246,9
  2 okt 370 392 415,3 440 466,2 493,9

Na vstup počítadiel timera vstupujú impulzy s frekvenciou ~ 1,19 MHz, preto treba pre generovanie tónu s frekvenciou 1kHz korigovať periódu kmitov faktorom 1331D=533H => pre frekvenciu f [Hz] treba pre určenie periódy použiť vzťah 1331/(f/1000)= 1331000/f = 144F38H/f.

Dĺžka tónu je určená typom noty:
 
  štvrťová nota - 250 ms polovičná - 500 ms celá - 1000 ms. 

Základom pre dĺžku tónu je oneskorovacia sľučka cwait , generujúca oneskorenie 10 ms, pretože inštrukcia:
 
  cwait: mov cx,n - trvá 4 takty
  repr: loop repr - trvá 17 taktov v sľučke resp. 5 taktov pri výstupe zo sľučky teda celkove (17*(n-1)+5+4) taktov.

Napr. pre PC PP06 je trvanie taktu T=210ns, takže potrebné číslo n = 2801. Samozrejme pre rýchlejší počítač s kratšim T bude treba  ináč korigovať n, lebo melódia prebehne príliš rýchlo. (Možte si to overiť zmenou prepinača Turbo na prednom paneli PC).

Procedúra Sound - Pgn151b.asm vyberie z tabuľky údaj frekvencie f a vynásobí periódu generovaných impulzov T = 1/f vhodnou konštantou 533H*1000 = 1331000 = 144F38H, korigujúcou odchylku vstupnej frekvencie timera 1,19MHz od hodinovej frekvencie 1MHz (napríklad pre generovanie 1kHz treba uložiť do počitadla 1331 = 533H). Dĺžka tónu je určená rýchlosťou počítača a počtom prechodov cez oneskorovaciu sľučku. (Rýchlosť PC PP06 napríklad požaduje pre oneskorovaciu slučku o trvani 10ms uložiť 2801 do registra počitadla BX). Je jasné teda, že rytmus melódie bude na rôznych počítačoch odlišný.
 
  Vstup: DI - frekvencia tónu (21 - 65535 Hz)
    BX - trvanie tonu ( 0-65535)- (dlžka tónu v násobkoch 10ms)

     ;-----------------------------------------------------------
 ccode
segment para  public"CODE"
  assume cs:ccode  
 Sound 
 proc far  
  public sound  
  push ax ;--------------
  push bx ;Úschova
  push cx  
  push dx  
  push di ;--------------
  mov al, 0b6h ;režim SC_2
  out 43h, al  
  Mov dx, 14h ;delit 1333000/f
  mov ax, 4f38h  
  div di  
  out 42h, al ;Lsb uložit
  mov al, ah  
  out 42h, al ;Msb uložit
  in al, 61h   ;zistit stav PB
  mov ah, al  
  or al, 3 ;zap reproduktor
  out 61h, al  
 cwait: mov cx, 2801 ;dlžka = 10 ms
 repr: loop repr  
  dec bx  
  jnz cwait ;---------------
  mov al, ah ;Obnova
  out 61h, al  
  pop di ;---------------
  pop dx  
  pop cx  
  pop bx  
  pop ax  
  ret  
 sound 
endp  
 ccode 
ends  
  end  
    ; --------------------------------------------------


µ  Meranie časových intervalov 

 
4a. Meranie  času s pomocou služieb BIOS a DOS 

Na meranie dlhších intervalov od 55 ms do 5 s možno použiť služieb BIOSu a DOSu, ktoré sú založené na počítaní 55ms tikov hodín reálneho času.
 

q BIOS - INT 1AH

Obslužná subrutina BIOS - INT 1AH zistí, resp. nastaví aktuálny čas v počte 55 ms tikov hodin, ktoré sú obsahom registovej dvojice CX: DX. INT 1AH pri vstupe:
 
  ah = 0 - zistí aktuálny stav CX: DX 
  ah = 1 - nastaví požadovaný stav CX: DX 



Pgn7.asm - použitie prerušenia BIOS INT 1AH
Príklad obsluhy BIOS - INT 1AH, ktorý sa normalne používa na zistenie stavu počítadla časových tikov (s frekvenciou f=1/55ms~18,206Hz) realneho času, na generovanie náhodného čísla 1 až 6 pre elektronickú hraciu kocku. Procedúra na začiatku umožňuje zadať číslo 1 - 6 s cieľom uhádnuť generované číslo, odvodené z časového údaja. Výstup z programu po zadaní - x.

Procedúra Pgn7.asm - kocka slúži podobne ako elektronická hracia kocka na generovania náhodného čísla od 1 do 6. Na generovanie pseudonáhodného čísla sa využíva obsah registrov CX:DX, merajúcich reálny čas pomocou prerušenia BIOS -INT 1AH (resp. vydelením (DX) = 16 LSB zvyšku počitadla hodinových tikov => (DX)/6 +1)). Hra, spočívajúca v uhádnutí vygenerovaného čísla, sa začína po zadní - w a ukončí sa návratom do DOS po zadaní - x.
 
     ;------------------------------------------------
 stackx 
Segment para  stack"stack"
  Db 6 dup ("STACK") ;zaplni stack
 stackx 
ends ;6 * "stack"
 txtcode 
Segment para  "code"
  assume cs :txtcode,  ss:stackx
  kocka proc   
  mov ah, 15  ;status videostránky
  int 10h  
  nast_nul:  
  sub cx,cx ;vynulovanie aktuál. času cx
  sub dx,dx ;vynulovanie aktuál. času dx
  mov ah,1 ;Nastaviť CX, DXo na nulu
  int 1ah  
 test_otaz:    
  mov dl,0ffh ;Číta 1 znak
  mov ah,6  
  int 21h  
  cmp al,"w" ;test w
  je vystup ;ak ano výstup náhod čisla
  cmp al,"x" ;test x
  je pgm_end ;ak nie hrá sa ďalej
  jmp test_otaz  
 vystup:    
  mov dh, 24 ;riadky
  mov dl, 60 ;stlpce
  mov bh, 0 ;videostrana
  mov ah, 2 ; kurzor dolu vpravo
  int 10h  
  mov ah, 0 ;číta údaj o čase
  int 1ah ;do CX 16MSB, do DX 16LSB
  mov ax, dx ;ulož lsb časť údaja
  and ax, 1fffh  
  mov dl, 6 ;deli 6, podiel=(AL),
  div dl ;(AH)=zvysok =0 až 5
  mov al, ah ;zvysok do al
  add al, 31h ;do ASCII +1=>od 1 po 6
  mov ah, 14  ;vystup na obrazovku
  int 10h  
  jmp nast_nul  
 pgm_end:    
  mov ah, 4ch ;navrat do DOS
  int 21h   
 kocka 
endp  
 txtcode 
ends  
  end kocka  

q DOS - INT 21H/ ah = 2CH

Obslužná subrutina DOS - INT 21H / ah = 2CH slúži na zistenie aktuálneho času v tvare HH:MM:SS:XX (hodiny: minúty: sekundy: stotiny sekúnd ).

Pgo63.asm - použitie prerušenia DOS INT 21H / ah = 2CH

Príklad použitia obsluhy DOS - INT 21H / ah=2CH (ktorý sa normalne používa na zistenie aktuálneho reálneho času) na generovanie oneskorenia dlhšieho ako 10 ms metódou štart - stop, podobnou spôsobu ako pracujú stopky.
 

Procedúra Pgo63.asm -Delay generuje oneskorenia metódou štart - stop podobne ako stopky. Táto procedúra je vhodná tiež ako subrutina na generovanie oneskorenia - dlhšieho ako 0.01s. Pred spustenim programu treba uložiť do registra AL -počet minút, do registra BH - počet sekúnd a do registra BL - počet stotín sekúnd želaného oneskorenia. Na začiatku programu sa zistí aktálny čas, potom sa k nemu pripočíta želané oneskorenie a testuje sa kedy nastane takto predvolený čas.
 
 
 ccode
segment para public   "code"
  assume cs:ccode  
 delay 
 proc far  
  public delay ;ináč vyhadzuje linker chybu !!!
  push ax ;Úschova
  push bx  
  push cx  
  push dx  
  mov ah, 2ch   ;zisenie aktuálneho času
  int 21h  
     ;Pripočítať zadefinované oneskorenie z registrov AL a BX k aktuálnemu času
  mov ah, ch   ;hodiny
  add al, cl   ;minuty
  add bh, dh   ;sek
  add bl, dl   ;1/100 s
     ;Skorigovať nastavené dáta, aby stotiny<100, sek<60, min<60, hod<24.
  cmp bl, 100   ;stotiny<100?
  jb secs  
  sub bl, 100   ;ak sú >100 => odčitat
  inc bh   ;a min+1
 secs: cmp bh, 60   ;sek < 60?
  jb mins  
  sub bh, 60   ;treba korigovat
  inc al  
 mins: cmp al, 60 ;min<60?
  jb hrs  
  sub al, 60   ;treba korigovat
  inc ah  
hrs: cmp ah, 24   ;hod<24
  jne check   
  sub ah, ah  
     ;Čakanie pokiaľ nenastane vypočitaný čas
 check: push ax   ;znova test času
  mov ah, 2ch  
  int 21h  
  pop ax  
  cmp cx, ax   ;porovná hodiny a minuty
  ja quit  
  jb check  
  cmp dx, bx ;porovná sek a stotiny
  jb check  
 quit: pop dx  
  pop cx  
  pop bx  
  pop ax  
  Ret  
 delay 
endp  
 ccode 
ends  
  end   ;Ako subroutina



Pgn5.asm - iné použitie prerušenia DOS INT 21H / ah = 2CH

Príklad použitia obsluhy DOS - INT 21H / ah=2CH, ktorý sa normalne používa na zistenie aktuálneho reálneho času, na generovanie čísla 1 až 9 v sekundových intervaloch so zobrazením. Výstup z programu po zadaní - x. (Na začiatku procedúry sa zdanlivo zbytočne nastavuje mód obrazovky - takéto ošetrenie stavu prostredia nie je obecne na závadu.)
 
 
  page,132  
  title  Generovanie 0-9 pomocou timera. Koniec progrramu ak "x"
    ;-------------------------------------
stackx 
Segment para stack   "stack"
  db 10 dup ("STACK")   ;zaplni stack
stackx 
ends   ;10x "STACK"
     ;-----------------------------------
 textcode 
Segment para "code"  
  assume cs :textcode,  ss:stackx
 time_pgm 
proc   
  sti   ;uvolnenie int
       ;-----------------------------------
 ukazat: mov ah,15   ;cita videostatus
  int 10h  
        ;-----------------------------------
  mov ah,2   ;nastavenie kurzora
  mov dh,24   ;riadky
  mov dl,60 ;stlpce
  int 10h  
       ;-----------------------------------
 slucka: mov ah,2ch ;cita cas z timera SC0
  int 21H    ;CH=h,CL=m,DH=s, DL=.01s,AL=0/1
       ;-----------------------------------
  mov al,dh   ;uloz sekund
  mov bl,10 ;priprava na delenie /10
  sub ah,ah   ;vynul ah
  div bl   ;AX/bl=(AL),zvys=(AH)
  xchg al,ah   ;sek=zvys do AL
  add al,30h ;do ASCII
       ;-----------------------------------
  mov ah,10   vyst (AL) na curs poziciu
  mov cx,1   ;1=repeat count
  int 10h   
        ;-----------------------------------
  mov dl,0ffh ;test klavesu do AL bez wait
  mov ah,06h ;  
  int 21h  
  cmp al,"x" ;test "x"-koniec procedury
  jne slucka   ;inac opakovat
  mov ah,4ch   ;navrat do DOS
  int 21h  
 time_pgm 
endp  
 textcode 
ends  
  end time_pgm   




Spiel1.asm - iné použitie prerušenia DOS INT 21H / ah = 2CH

Príklad použitia obsluhy DOS - INT 21H / ah=2CH, ktorý sa normalne používa na zistenie aktuálneho reálneho času, na generovanie náhodného čísla 1 až 99 s cieľom uhádnuť ho, podobne ako v Pgn7.asm. Výstup z programu po zadaní - x. (Všimnite si použitie makra ausgabe na zobrazenie reťazca textu.)
 
 
     ;Program generuje nahodne cislo 0-99, 
     ktore treba uhadnut
  CR EQU 0DH ; Konstanten - Definition
  LF EQU 0AH  
     ; Macro - Definitionen
 ausgabe 
 macro te ;zobrazenie textového reťazca
  mov dx,offset te  
  mov ah,09h  
  int 21h  
  Endm  
    ; Data => oznamy ktore sa zobrazia
 daten 
segment  
 text1 
db CR,LF,  LF,'Pocitac vygeneruje cislo ',CR,LF
  db  'v rozmedzi 0 az 99.',CR,LF
  db   'Toto cislo skuste uhadnut.',CR,LF
  db   'Po zadani . sa zakonci program.',CR,LF
  db   'Prosim zadajte Vase 2 cislice: ',CR,LF,LF,'$'
 text2 
db  CR,LF,LF
  db   'Volba nebola spravna. Vase cislo je privelke.'
  db  ' Nasledujuci pokus ',CR,LF,'$'
 text3 
db CR,LF,LF  
  db   'Volba nebola spravna. Vase cislo je primale.'
  db   ' Nasledujuci pokus ',CR,LF,'$'
 text4 
db CR,LF,LF  
  db   'Toto cislo je spravne. Bomba!!!! $'
 ein 
db   3,0,0,0,0 ; Vstupny buffer
 daten 
ends  
     
 stack 
segment stack  ; Stack -Bereich
  dw 4096 dup(0)  
 stack 
ends  
     
     
 code 
segment  ; Programova oblast
  assume cs:code, ds:daten,es:daten,ss:stack
 start:    
  mov ax,daten   ; ds = es nastavit
  mov ds,ax   
  mov es,ax  
     
  mov ah,2ch  ; Cas cita (v dl stotiny sekund)
  int 21h ;  
  mov al,dl  
  aam   ; Prevoddo ASCII - Formatu
  or ax, 3030h ; ASCII - Bity pridat
  mov si,ax   ; si ako referencna hodnota, nebude
     ; neskor pouzivana
  ausgabe text1 ; Vystup oznamu
 schleife:    
  mov ah,0ah  
  mov dx,offset ein  
  int 21h   ; Vstup cisla
     
  mov dl,byte ptr ein+2   ; Byte - Swap nutny !
  mov dh,byte ptr ein+3  
  mov byte ptr ein+2,dh  
  mov byte ptr ein+3,dl  
  cmp word ptr ein+2,si  
  je ende   ; Cislo OK - > Hlasenie o konci
  ja gross   ; Cislo velke
 klein:    
  Ausgabe text3   ; Oznam
  jmp schleife  
 gross:    
  Ausgabe text2  ; Oznam
  jmp schleife  
 ende:    
  Ausgabe text4  ; Uspesny oznam
  mov ax,4c00h  
  int 21h  ; Program zakoncit
     
 code 
ends  
  end start  


 
4b. Meranie krátkych intervalov pomocou timera 8253

Pre tento účel možno s výhodou použiť snímanie systémového času "za jazdy" priamo z počitadla SC_0, ktorého vstupné impulzy majú frekvenciu PCLK / 2 = 1.19 MHz.

Bfig_85.asm- odmeranie periódy obdlžnikových impulzov

Príklad demonštruje meranie krátkych intervalov (od 870ns do 27ms), napr. s cieľom odmerať trvanie generovaných impulzov na výstupe počítadla timera SC_2, pomocou stopiek založených na zosnímaní aktuálneho stavu počítadla SC_0, metódou štart - stop, v okamihoch skoku amplitúdy meraného impulzu. Problem, že momentálne v tomto tvare na všetkých PC nechodí ? Asi treba vložiť viac NOP na ustálenie timera.
 

Procedúra Timer umožňuje odmerať trvanie periódy impulzov obdlžnikového tvaru generovaných na výstupe OUT_2 počítadla SC_2 , ktoré sú k dispozícii na výstupoch PC_6 a PC_5 portu s adresou 62H. Meranie sa vykoná pomocou stopiek založených na zosnímaní aktuálnych obsahov bežiaceho počítadla SC_0 v 2 rôznych okamihoch: tstart a t stop .Dĺžka odmeraného intervalu t stop - tstart , vyjadrená v počte periód T = 1/(1,19MHz) = 840 ns počitadla SC_0, je potom po skončení procedúry Timer v registri BX. Na určenie začiatku a konca merania sa využíva procedúra Low_to_High, pomocou ktorej možno identifikovať skok úrovne L - H a tak určiť okamihy tstart a t stop Činnosť počítadla SC_2 je zadefinovaná riadiacim slovom B6H, ktorým je učený BIN kód počítania v móde 3 a spôsob ukladania 16 bit predvoľby v poradí LSB a potom MSB. Činnosť počitadla SC_0 je implicitne nastavená pri bootovaní počítača. Pre aktivovanie činnosti počitadla treba ešte zabezpečiť logické úrovne “H” na PB_0 a PB_1 portu PB na adrese 61H.
 
 
 stackseg 
segment para stack   
  Db 64 dup("stack")  
 stackseg 
ends  
     ;-----------------------------------
 code 
segment  
  assume cs:code,  ss:stackseg
 timer 
proc far  
  push ds  ;Úschova pre navrat do DOS
  mov ax, 0  
  push ax  
     ;Nastavenie sc2: mod 3, 16 bit Read/Load ,bin kód
  MOV AL, 0B6h   ;Nastavenie počitadla SC_2
  OUT 43h, AL   ;riadiaci reg
  MOV AX, 533h   ;SC2 s frekvenciou 1kHz
  OUT 42h, AL   
  MOV AL, AH   
  out 42h, al  
  in al, 61h  
  push ax  ;úschova pôvodneho stavu 61h
  or al, 01  ;uvoľnit vstup Gate SC2
  out 61h, al  
  call low_to_high   ;start => test skoku L-H
  mov bx, ax  ;Úschova začiat stavu vBX
  call low_TO_HIGH   ;stop merania
  sub bx, ax  ;Rozdiel 2 merani v BX
  Pop ax  ;obnova 61h
  out 61h, al  
  Ret  
 timer 
endp  
     ;-----------------------------------
     ;Subrutina uloží stav SC0 do AX v okamihu prechodu L-H. vystupu SC_2
 low_to_high 
Proc near  
  in al, 62h ;Test 5. bitu výstupu PC5
  test al, 20h  
  jnz low_to_high ;pokiaľ nie je 0
 wait_high:    
  in al, 62h  ;Znova test bitu 5 pokiaľ
  test AL, 20H ;nebude na urovni H
  jz WAIT_HIGH  
  mov al, 0 ;Štart merania za chodu
  out 43h, al  ;zachyti stav SC_0
  nop  ;Oneskorenie na ustálenie
  Nop  
  in al, 40h  ;Čita LSB počitadla SC0
  mov ah, al   
  Nop  
  in al, 40h  ;Čita MSB SC0
  xchg ah, al  ;do AX
 low_to_high 
Ret  
  endp  
 code 
ends  
  end timer ;Začiatok programu
     ;-----------------------------------


 
µ Kontrola funkcie timera pomocou osciloskopu

Na overenie parametrov generovaných impulzov z timera slúži prípravok s obvodom 8253 umiestnený na špeciálnej interfejsnej karte na adresách 71CH až 71FH, ktorého niektoré vstupy a výstupy sú prístupné pre sondu osciloskopu. Na operatívnu zmenu vstupných parametrov timera je k dispozícii port 1PA s tlačítkovým vstupom a na zobrazenie odmeraného trvania impulzu výstup LED na porte 1PB.
 
Obr. 5-5. Zapojenie timera v meranom prípravku.

 

Tim2.asm - Kontrola timera, pracujúceho v móde 2 a 3, pomocou osciloskopu.

Cieľom demonštrácie je generovanie impulzov s obvodom 8253 na interfejsovej karte, ktorého počitadlá sú nastavené v rôznych módoch (=> SC_2 / mód2; SC_1 / mód2; SC_0 / mód3) a ich kontrola pomocou osciloskopu.

Meraný obvod timera 8253 je zapojený na interfejsovej karte k počítaču PP06. Jeho počítadlá SC_2 a SC_1 sú na karte zapojené za sebou tak, že do počítadla SC_2 vstupujú impulzy s frekvenciou f (pre PP06 s frekvenciou f=(4,47/ 16) MHz = 279kHz alebo s periódou T~°3,58ms). Výstup OUT_1 počítadla SC_1 spolu s hradlovacím vstupom GATE_1 sú prístupné cez konektory na paneli, rovnako ako vstupy IN_0, GATE_0 a výstup OUT_0 počítadla SC_0. Preto je pomocou nich a osciloskopu možné sledovať činnosť sériovo zapojených počítadiel timera na výstupe OUT_1 a OUT_0. Kvôli demonštrácii činnosti počítadiel sú naprogramované v procedúre na vykonanie nasledovných činnosti:

  • Obe počítadla SC_2 a SC_1 sú nainicializované do módu 2 s minimálnym deliacim pomerom n1=2 v SC_1 a minimálnym deliacim pomerom n2= 2 v SC_2 (potom neskôr v programe bude možno meniť deliaci pomer SC_2). Posledné počítadlo SC_0 je nainicializované do módu 3 s minimálnym deliacim pomerom n0=4. (Pri počítadlách SC_0 a SC_1 bol zvolený spôsob, ktorý predpokladá, že v ďalšej časti programu sa bude meniť ich deliaci pomer len pomocou 1 LSB z tlačítiek.) Pri testovaní programu zapojte osciloskop na výstup OUT_1 a odmerajte trvanie a frekvenciu generovaných impulzov a porovnajte ich s hodnotami, určenými na základe deliaceho pomeru n1n2 = 4 a frekvencie f. (Aká je frekvenciu a tvar generovaných impulzov na výstupe SC_2? Je frekvencia na výstupe OUT_1= 4,47MHz/16 ~ 279kHz a trvanie generovaného impulzu ti=6,7ms?).
    1.  
  • V ďalšej časti programu po nainicializovaní posledného počítadla SC_0 do módu 3 s minimálnym deliacim pomerom n0=4 odmerajte frekvenciu a určite tvar generovaných impulzov na výstupe OUT_0. Modifikujte deliaci pomer na n0=2 (n0=20) a sledujte ako sa pozmení frekvencia a trvanie generovaného impulzu. (Je ti=2*6,7ms, resp. ti=4*6,7ms, ti=20*6,7ms)

  •  
  • Potom v ďalšej časti programu po nainicializovaní počítadiel zabezpečte, aby sa deliaci pomer počítadla SC_1 dal ovládať pomocou vstupných tlačítiek z portu 1PA. (Pretože vstupný údaj z tlačítiek je 8 bit široký treba nainicializovať počítadlo SC1 pomocou riadiaceho slova CW12L tak, aby na zadefinovanie deliaceho pomeru postačoval len dolný menej významný bajt - LSB slova deliaceho pomeru, ktorého maximálna šírka môže byť normálne až 16 bit.) V prípade, že by bola na vstupných tlačítkach portu 1PA nastavena 0 alebo 1, tak počítadlo SC_1 prestane fungovať ako delička (po zmene nastavenia pri n > 1 bude znova pokračovať v generovaní impulzov). Preto program by nemal pripustiť tieto možnosti (s kódom 00H alebo 01H) nastavenia deliaceho pomeru.
  • Pomocou dvojlučového osciloskopu sledujte signál na výstupoch OUT_0 a OUT_1. (Všimnite si, že počítadlo pokračuje v nastavenom generovaní impulzov aj po skončení programu.) V ďalšej časti programu po nastavení počítadiel sa potom demonštruje (call citaj) snímanie stavu počítadla SC_1 počas jeho činnosti. Zosnímaný údaj sa zobrazí na LED na porte 1PB. (Porovnajte indikovaný údaj s nastaveným deliacom pomerom SC_1 na vstupných tlačítkach portu 1PA.) Táto činnosť spolu s nastavením aktuálneho stavu počítadla na základe zosnímaného údaja s portu 1PA tvorí programovú sľučku, ktorá má ošetrené (label @aa) zadanie kódu 00H z tlačítkového vstupu. Po zadaní kódu 01H z tlačítkového vstupu (skokom na @cc) sa ukončí program. 
;------------------- Tim2. asm ---------------------
;Demo 8253 SC2 v mode 2, SC1 v mode 2, SC0 v mode 3.
;CWTR je adresa riadiaceho registera, CWTR-1 je adresa SC2, CWTR-2 je adresa SC1 a pod.
Riadiace slovo :
;SC2,mod2 10 11 010 0B =>B4H = CW22 na adr ASC2
;SC1,mod2 01 01 010 0B =>54h = CW12L len LSB
;SC1,mod2 01 11 010 0B =>74H = CW12 na adr ASC1
;SC1,mod3 01 11 011 0B =>76H = CW13
;SC0,mod2 00 11 010 0B =>34H = CW02 na adr ASC0
;SC0,mod1 00 11 001 0B =>32H = CW01
;SC0,mod3 00 01 011 0B =>16H = CW03L len LSB
;----------------------------------------
 MODEL 
 small  
     ;----------------------------------------
 .STACK 
100h  
 .DATA
 
 Sprava 
DB  " SC_2 mod2 => n=1/2 ,  SC_1 mod2 =>n=1/2 => celkove 1/64 $"
  DB 13,10,"$"  
      ;----------------------------------------
 .CODE 
 
 CW22 
equ 0B4H  
 CW12L 
equ 54H  
 CW03L 
equ 16H  
 CWTR 
equ 71FH  
 POMSC0 
equ 4  ;deliaci pomer v SC_0 n = 4
 POMSC1 
equ 02H  ;deliaci pomer v SC_1 n = 2
 POMSC2 
equ 02H  ;deliaci pomer v SC_2 n = 2 skusit aj napr. 0A00H 
 porta1 
equ 700h ;defin portA=tlačitka
 portb1 
equ 701h  ;portB LED
 portc1 
equ 702h  
 CWR1
equ 703h  
      ;----------------------------------------
  mov dx, CWR1   ;nastavenie portov tlačítiek a LED
  mov al, 90  
  out dx, al  
  mov ax, @data   ;nastav DS
  mov ds, ax  
  mov ah, 9   ;DOS výstup reťazca s $
  mov dx, OFFSET Sprava   ;Nastavit relatívnu adresu
  int 21H   ;zobrazenie
  mov dx, CWTR   ;inicializácia SC2
  mov al, CW22  
  out dx, al  
  dec dx   ;nastavenie SC2
  mov ax, POMSC2  ;deliaci pomer
  out dx, al  ;LSB
  mov al, ah  
  out dx,   al ;MSB
  inc dx   ; inicializácia SC1
  mov al, CW12L  
  out dx, al  
  mov al, CW03L  ;inicializácia SC0
  out dx, al  
  dec DX  ; predbežné nastavenie SC1
  dec DX  
  mov al, POMSC1  
  out dx, al  ;len LSB
  dec DX  ; nastavenie SC0
  mov al, POMSC0  
  out dx, al  
  inc DX  ;adr SC1 na kontrolu
 @bb: push dx  
  mov dx, porta1  ;čita tlačitka PA
 @aa: in al, dx  
  not al  ;inverovanie vstupu z tlačítiek
  cmp al,0  ;koniec ak nestlacene tlacitka
  pop dx  
  jz @cc   
  cmp al, 01   ;čaka pokial su tlačítka=0
  jz @bb  
  out dx, al   ;LSB z tlačítiek do timera
  call citaj  
  jmp @bb  
 @cc: mov ah, 4ch  ;stop
  int 21h  
 citaj: push dx  
  push ax  
  mov dx,  CWTR  ;riad reg
  mov al, 40H   ;aby čitalo SC2 za chodu
  out dx, al  
  mov dx, CWTR-1  ;SC2
  in al,dx  ;Režim čítania len LSB
  nop ;ustálenie
  Nop  
  Nop  
  in al,dx  
  mov dx,porta1+1  
  out dx,al  
  pop ax  
  pop dx  
  Ret  
  END  

Úloha:
Tim3.asm - Generovanie impulzov

Úlohou je zostaviť program na ovládanie obvodu 8253 (na interfejsovej karte), ktorý by umožňoval generovať impulzy s rôznym trvaním a frekvenciou. Základná inicializácia počítadiel (SC_2 / mód2 s n2=2; SC_1 / mód3 s n1=2; SC_0 / mód2 s n0=4) je ovplyvnená možnosťou pozorovať impulzy na výstupoch OUT_1 a OUT_2. V takejto konfigurácii hrá počítadlo SC_2 (mód2 s n2=2) len úlohu deličky. Pomocou počítadla SC_1 (mód3 s regulovateľným n1=2 až 11) sa nastavuje trvanie impulzu ti. Pomocou počítadla SC_0 (mód2 s regulovateľným n1=  2 až 11) sa mení trvanie medzery medzi impulzami tm. Zmena parametrov generovaných impulzov sa uskutočňuje pomocou vstupu číslic 0 - 9 z klávesnice (podobne ako v getnum.com - s následným výpisom zadaného čísla na obrazovku). Základná rozhodovacia ponuka by mala mať možnosť voľby (napríklad obdobne ako v programe Bfig_428 alebo menu.bat) pre:

  • Trvanie impulzu ti - z počítadla SC_1;
  • Trvanie medzery medzi impulzami tm - z počítadla SC_0;
  • Koniec programu (po zadaní ESC)



 

[Návrat]