Elektroda.pl
Elektroda.pl
X
Relpol
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Opóźnienia czasowe w AT89C2051

Szybos 17 Wrz 2007 16:02 1269 11
  • #1 17 Wrz 2007 16:02
    Szybos
    Poziom 9  

    Witam. Mam pytanie. Czy w tym procesorze AT89C2051 istnieją tak zwane opóźnienia czasowe (oprócz rozkazu NOP). Chodzi mi o język programowania - asembler. Jeżeli tak to prosiłbym o podanie kawałka kodu jakby to wyglądało na podstawie sterowania diodami. Z góry dziękuje.

    0 11
  • Relpol
  • #2 17 Wrz 2007 16:17
    Jdsoul
    Poziom 23  

    Cześć jak zwykle metod jest wiele - sprzętowa i programowa.

    Programowa jest gorsza bo nic innego nie daje się wtedy zrobić

    Code:
    mov R0, #255
    
    skocz_tu:
    djnz R0, skocz_tu

    lub dłuższa czyli 255*255

    Code:
    mov R0, #255
    
    skocz_tu:

    mov R1, #255
    skocz_tam:
    djnz R1, skocz_tam

    djnz R0, skocz_tu

    Co do sprzętowej realizacji to niestety dłużej czyli ustawienie timer T0 lub T1 i przerwania . Potem w obsłudze przerwania ponowne ustawienie przerwania i td. itd itd.
    Zaleta można w między czasie przejrzeć gazetę , wypić kawę itd. obejrzeć wlagi wysłać inne rozkazy :) no ale to wyższa szkoła jazdy.

    0
  • #3 17 Wrz 2007 16:23
    ekspert100
    Poziom 16  

    Masz tu prosty przykład w .asm

    START:

    MOV P1,#127 ;Podstaw 01111111 do portu p1 #127
    Lcall TIME_N100 ;Wywołaj podprogram czas_n1
    MOV P1,#191 ;Podstaw 10111111 do portu p1 #197
    Lcall TIME_N100 ;Wywołaj podprogram czas_n1


    Sjmp START ;Skocz do etykiety

    ;***************************************
    ;podprogram opóznienie czasowe


    TIME_N100:
    PUSH ACC ;przechowaj na stosie
    ;licznik zewn©trzny

    MOV A,#5 ;zacznij odlicza† 100ms
    TIME_100: ;odliczanie 200 * 0.5ms
    PUSH ACC ;2 cykle
    MOV A,#101 ;2 cykle
    DJNZ ACC,$ ;226*2=452 cykle
    POP ACC ;2 cykle
    DJNZ ACC,TIME_100 ;2 cykle
    ;razem 460 cykli=0.5ms

    POP ACC ;odtw˘rz licznik
    DJNZ ACC,TIME_N100 ;odlicz N*100ms

    Lcall TIME_N100

    RETI





    ;************************************************************
    TEXT:
    DB '"EKSPERT" Systemy'
    DB ' Mikroprocesorowe'
    DB ' STER LINIE 06 '
    DB ' VER - 5 CZARO ',0


    End ;Koniec kodu programu

    0
  • Relpol
  • #4 17 Wrz 2007 21:08
    Szybos
    Poziom 9  

    Czy ten przykład dobrze jest napisany, bo jakoś dioda mi nie miga, albo może nie ma takich zamiarów ten program :)

    0
  • #5 18 Wrz 2007 08:54
    Jdsoul
    Poziom 23  

    ALe pierwszy program czy drugi :)

    0
  • #6 18 Wrz 2007 14:29
    Szybos
    Poziom 9  

    Drugi :) A nie słyszeliście może o funkcji sleep bo mi sie obiło o oczy kiedyś takie coś, a może wiecie jak zamienić plik .hex na .asm w czystej "rozkazowej" postaci :)

    0
  • #7 18 Wrz 2007 14:54
    Krzych51
    Poziom 14  

    Szybos napisał:
    Drugi :) A nie słyszeliście może o funkcji sleep bo mi sie obiło o oczy kiedyś takie coś, a może wiecie jak zamienić plik .hex na .asm w czystej "rozkazowej" postaci :)


    Witam.
    Zmiana pliku .hex na .asm to deasemblacja, instnieją programy które potrafią tego dokonać. Poszukaj w internecie pod hasłem "Disassembler", napewno coś znajdziesz. Może to: http://www.circuitseed.com/Micro%20tools/803151%20disassembler.htm

    Pozdrawiam Krzych

    0
  • #8 18 Wrz 2007 14:59
    ekspert100
    Poziom 16  

    Sorki ale zabrakło

    Sjmp START ;Skocz do etykiety

    teraz masz uzupełniony powinno być ok.

    0
  • #9 18 Wrz 2007 23:20
    Krzych51
    Poziom 14  

    Witam ponownie.
    Wracając do tematu opóźnienia w uC 51, można też wykorzystać działający timer który generuje cyklicznie przerwanie. Zliczając przerwania i znając częstotliwość ich powstawania można precyzyjnie odmierzać czas i mieć odpowiednio długie opóźnienia.
    Pozdrawiam Krzych

    0
  • #10 19 Wrz 2007 16:01
    Szybos
    Poziom 9  

    A byłaby taka możliwość, że np wprowadzam na port P1 stan 01111111 i chciałbym, żeby on utrzymywał sie przez odpowiednia liczbę czasu :) Czyli, że jeżeli była by to dioda to świeciła by sie ona przez 1s albo 2s :) A później zmieniam stan i tak dalej

    0
  • #11 20 Wrz 2007 17:47
    ekspert100
    Poziom 16  

    Witam!!!

    Jeśli wskazwóki są pomocne korzystaj z przycisku pomógł !!!


    ;***************************************
    ;podprogram opóznienie czasowe
    ;najpierw
    ;podprogram

    time_n100:
    push acc ;przechowaj na stosie
    ;licznik zewn©trzny

    mov a,#5 ;zacznij odlicza† 100ms

    (mov a,#5) ten rozkaz decyduje o tym
    ile razy ma być uruchomiony podprogram time_100:

    time_100=100ms*5=500ms

    jak wpiszesz mov a,#8
    time_100=100ms*8=800ms

    0
  • Pomocny post
    #12 24 Wrz 2007 10:02
    Jdsoul
    Poziom 23  

    Generalnie port jest zatrzaskiem więc nie ma sensu się martwić czy dana informacja się zmieni czy nie do czasu kolejnego zapisu do portu :)

    To daje ci sytuację taką korzystną sytuację że nie musisz się martwić o to co rozbi procek w tym czasie.

    Pytanie jak bardzo zależy ci na dokładności odmierzenia czasu w przypadku zapalania diody na około 1s lub około 2s. To zmiany są niezauważalne :) więc wystarczy odpowiednia zamknięta pętla .

    Stosowanie opóżnień programowych powoduje zablokowanie kontrolera w pętli i nic innego nie jest wtedy wykonać. Więc najlepiej jest zastosować pętlę w pętli z testowaniem jakiegoś warunku np. naciśnięcia klawisza , przychodzącego znaku czy jeszcze czegoś, a całkowite opóźnienie uzyskać jako sumę n-małych opóżnień

    Przykład

    Code:
    for (;;) /*pętla nieskończona */
    
    {

     while (i < 100) do /*Pętla co 100 ms:*/
    {   
       readkey(); /* Testowanie klawiatury */
       getRX();      /* Testowanie znaku z RS-232*/
       Wait (1ms); /* Oczekiwanie 1 ms*/
       i++;
       
    };
    setport(P1);  /*Ustawienie portu P1*/
    };


    W ten sposób oszczędzasz "moce" procesora i zwiększasz lub zmniejszasz rozdzielczość odczytów znaku, klawiszy, aż do wielkości bliskich szybkości
    odczytu i zapisu urządzeń :) a jedna milisekunda w lewo czy w prawo na diodzie lub przekaźników nic nie zmieni

    Jeśli jednak dokładność ma być dużo wyższa zalecam timer stabilizowany kwarcem :) i przerwanie licznikowe :) pamiętaj tylko że obsługa przerwania też zajmuje jakiś czas :)

    0