1.2.16. Počítač meria čas

 

Dosť často budete chcieť, aby program nebežal po stanovenú dobu (čas na prezretie nakresleného obrázku, prečítanie textu, ...). Vtedy použijeme príkaz PAUSE v tvare:

      PAUSE číslo

kde číslo je celé číslo od 0 do 65535.

Týmto príkazom sa zastaví vykonávanie programu na čas, ktorý je určený číslom. Jednotkou parametra číslo je 1/50 sekundy, teda čas zastavenia programu v sekundách bude číslo/50.

Číslo=0 znamená zastavenie vykonávania programu až do stlačenia nejakého klávesu.

Ukončenie príkazu PAUSE je možné stlačením nejakého klávesu.

Príkaz PAUSE využijeme v programe pre nakreslenie chodu hodín:

       10 REM prvy urobime cifernik

       20 FOR n=1 to 12

       30 PRINT AT 10-10*COS (n/6*PI), 16+10*SIN (n/6*PI);n

       40 NEXT n

       50 REM teraz nastartujeme hodiny

       60 FOR t=0 TO 200000: REM t je cas v sekundach

       70 LET a=t/30*PI: REM a je uhol sekundovej rucicky

          v radianoch

       80 LET sx=72*SIN a:LET sy=72*COS a

      200 PLOT 128,88: DRAW OVER 1;sx,sy: REM kresli sekundovou

          rucicku

      210 PAUSE 42

      220 PLOT 128,88: DRAW OVER !;sx,sy: REM maze sekundovou

          rucicku

      400 NEXT t

Hodiny pôjdu asi 55,5 hodín, čo je dané riadkom 60, ale môžete to ľahko zmeniť. Všimnite si, ako je čas na riadku 210 zadaný. Asi ste čakali PAUSE 50, ale výpočet tiež zaberie nejaký čas. Údaj v PAUSE budete musieť zrejme opraviť podľa chyby, ktorú hodiny vykazujú, ak sa porovnávajú s reálnym častom (hodiny idú s presnosťou asi 2 %).

Ak chcete presnejšie hodiny, použite nasledujúci postup, ktorý používa obsah určitej časti pamäti, ktorá sa nastavuje riadiacim programom Vášho počítača v závislosti od času. Uchované dáta sa vyberajú pomocou funkcie PEEK. Nasledujúci výraz

      t=(65535*PEEK 23674+256*PEEK 23673+PEEK 23672)/50

je počet sekúnd od zapnutia počítača (po 3 dni a 21 hodín potom sa mení na 0 a počíta ďalej).

Upravený program pre hodiny bude potom:

 10 REM najskor urobime ciselnik

       20 FOR n=1 TO 12

       30 PRINT AT 10-10*COS (n/6*PI),16+10*SIN (n/6*PI);n

       40 NEXT n

       50 DEF FN t()=INT ((65536*PEEK 23674+256*PEEK 23673+PEEK

          23672)/50) :REM pocet sekund od zaciatku

      100 REM teraz nastartujeme hodiny

      110 LET t1=FN t()

      120 LET a=t1/30*PI : REM a je uhol sekundovej rucicky

          v radianoch

      130 LET sx=72*SIN a: LET sy=72*COS a

      140 PLOT 128,88: DRAW OVER 1=;sx,sy: REM nakresli rucicku

      200 LET t=FN t()

      210 IF t=t1 THEN GO TO 200: REM pockaj, az je cas na

          dalsiu rucicku

      220 PLOT 128,88: DRAW OVER 1; sx,sy: REM maze staru

          rucicku

      230 LET t1=t: GO TO 120

Vnútorné hodiny, používajúce túto metódu, majú presnosť asi 0,01%. Tieto hodiny  však dočasne zastaví, ak použijete príkaz BEEP, alebo operácie s magnetofónom. Čísla na adresách 23674, 23673 a 23672 sú uložené v pamäti počítača a sú použité pre počítanie 50-nách sekundy. Každé je v rozmedzí od 0 do 255, po 255 sa vracia na 0. Najčastejšie sa mení číslo na adrese 23672 (najnižší rád). Vždy za 1/50 sekundy sa zväčší o 1. Keď je 255, v nasledujúcom kroku sa zmení na 0 a v rovnakom čase sa zvýši číslo na adrese 23673 o 1. Keď má toto hodnotu 255 a mení sa na 0, zároveň číslo na adrese 23674 sa zvýši o 1. Zväčšenie hodnôt sa vykonáva automaticky prerušením tak, že vykonávanie programu v jazyku BASIC sa zastaví, vykoná sa podprogram v strojovom kóde pre zmenu systémového času a vykonávanie programu v jazyku BASIC pokračuje. Toto prerušenie je časovo také malé, že ho nezaregistrujete.

Teraz starostlivo uvažujte. Predpokladajme naše tri čísla: 0 (pre adresu 23674), 255 (pre adresu 23673) a 255 (pre adresu 23672). To znamená, že čas v sekundách je

      (65536*0 + 256*255 + 255)/50=1310.7

Ale je tu nebezpečenstvo. Práve sa ukončilo vyhodnotenie funkcie PEEK 23674 (hodnota 0) a nastalo nasledujúce prerušenie. Hodnoty v pamäti sa zmenia na 1, 0, 0 a až potom nasleduje vyhodnotenie funkcií PEEK 23673 a PEEK 23672 (teraz majú hodnoty 0, 0). Preto platí:

      t = (65536*0 + 256*0+0)/50=0

čo je pochopiteľne chybne. Tomuto problému sa vyhneme tak, že budeme počítať čas 2 krát a vezmeme väčšiu hodnotu.

Tu je úprava pre uvedený postup. Definujte

      10 DEF FN m(x,y)=(x+y+ABS(x-y))/2:REM vacsie z x a y

      12 DEF FN u()=(65536*PEEK 23674 + 256*PEEK 23673+PEEK

         23672)/50: REM cas moze byt chybny

      14 DEF FN t()=FN m(FN u(),FN u()):REM spravny cas

Hodnoty v pamäti môžete však aj nastaviť, napr. nastavíme čas na 10 hodinu dopoludnia:

      10*60*60*50=1800000=65536*27 + 256*119+64

Na nastavenie hodnôt na 27,119, 64 použijete:

      POKE 23674,27: POKE 23673,119: POKE 23672,64