Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

opóźnienie - ale jak

rdt
-
-
Posty:87
Rejestracja:20 sie 2003, o 18:03
Lokalizacja:100km od Wawy
opóźnienie - ale jak

Postautor: rdt » 10 mar 2007, o 21:39

Witam
mam takie pytanie
jak w asemblerze dla 89c4051 zrobić wstawke która nic nie robi tylko odczekuje powiedzmy okolo sekundy
w bascomie dość często zmuszony jestem do korzystania z instrukcji wait lub waitms a każda z nich zabiera 4 bajty
i chodzi mi o to aby instrukcje tą zamienić na jakaś wstawkę asemblerową tak aby zajmowała mniej instrukcja nie musi opóźniać dokładnie o 1 sekundę - może o pół albo o dwie jak - czy ktoś coś podpowie ????

shadow82
-
-
Posty:12
Rejestracja:8 lis 2006, o 15:17
Lokalizacja:Trójmiasto
Kontaktowanie:

Postautor: shadow82 » 11 mar 2007, o 00:18

Utwórz sobie podprogram, w którym będzie tylko instrukcja Wait:

Kod: Zaznacz cały

Declare Sub MyWait '*** Code *** instr1 instr2 call MyWait - 2 bajty instr3 '************ Sub MyWait Wait 1 End Sub
To jest najprostrze rozwiązanie. Niezależnie czy opóźniewnie będzie w basicu czy asemblerze, to będziesz się do niego odwoływał przez "call".

rdt
-
-
Posty:87
Rejestracja:20 sie 2003, o 18:03
Lokalizacja:100km od Wawy

Postautor: rdt » 11 mar 2007, o 14:17

ok tylko ze wywołnie takiej funkcji powoduje zużycie 2 bajtów - a powrót - a to zeby adres powrotny zapamietac a potem zdjąć ze stosu - po kilku skokach bez zdejmowania nastąpi przepełnienie stosu i reset procka

teedd
-
-
Posty:14
Rejestracja:3 cze 2003, o 15:54

Postautor: teedd » 11 mar 2007, o 22:22

Witam.
Mylisz się pisząc, że waitms lub wait zajmuje 4 bajty. Te instrukcje po prostu wywołują odpowiedni podprogram w asemblerze, gdzie sam podprogram zajmuje więcej miejsca.
teedd

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Postautor: pajaczek » 11 mar 2007, o 22:34

Coz... tego sie poprostu NIEDA zrobic w 2 instrukcjach (4 bajtach). No chyba ze naprawde krotki wait (mieszczacy sie w kilkuset cyklach maszynowych, tak by za licznik wystarczyl bajt - np.: inc i branch_if_not_equal).

rdt
-
-
Posty:87
Rejestracja:20 sie 2003, o 18:03
Lokalizacja:100km od Wawy

Postautor: rdt » 15 mar 2007, o 20:54

Witam.
Mylisz się pisząc, że waitms lub wait zajmuje 4 bajty. Te instrukcje po prostu wywołują odpowiedni podprogram w asemblerze, gdzie sam podprogram zajmuje więcej miejsca.
teedd
hmm w polskim helpie stoi jak byk - 4 bajty
mało tego - sprawdziłem empirycznie juz dawno temu ze zajmuje to 4 bajty
nie wiem jak jest z dłuższymi wartościami - ale przeważnie używam około 3 sekund
p.s.
właśnie sprawdziłem - waitms zajmuje więcej bo 22 bajty
co do wait zajmuje 4 bajty jak pisałem wyżej niezależnie czy to wait 1 czy wait 1000

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Postautor: pajaczek » 15 mar 2007, o 22:48

wait zajmuje 4 bajty jak pisałem wyżej niezależnie czy to wait 1 czy wait 1000
To powtorze jeszcze raz: Tego sie nie da zrobic w 2 instrukcjach (4 bajtach).

Jesli ktokolwiek jest innego zdania, prosze mnie oswiecic, bo jak Tomasz: nie uwierze poki nie zobacze.

rdt
-
-
Posty:87
Rejestracja:20 sie 2003, o 18:03
Lokalizacja:100km od Wawy

Postautor: rdt » 16 mar 2007, o 20:41

.........................CIACH................................

Jesli ktokolwiek jest innego zdania, prosze mnie oswiecic, bo jak Tomasz: nie uwierze poki nie zobacze.
no więc tak - mówisz i masz - jeżeli masz bascoma to sam sprawdź a jezeli nie - to jak nie uwierzysz to trudno
obejrzyj ten sam kod z małą modyfikacją "wait 100" oraz wyniki po kompilacji
Ok jezeli masz coś do dodania to czekam z niecierpliwością
Załączniki
bascom1.jpg
bascom2.jpg

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Postautor: pajaczek » 17 mar 2007, o 00:20

no więc tak - mówisz i masz - jeżeli masz bascoma to sam sprawdź a jezeli nie - to jak nie uwierzysz to trudno
Nie mam... teraz to nie mam zadnego srodowiska ;/ ale to sie niedlugo zmieni.

Nie rozumiesz... to jest niemozliwe by to zrealizowac, bascom widocznie wykozystuje tu jakas procedurka ktora tak czy siak umieszcza w kodzie, te 4 bajty ktore przybywaja to jest prawdopodobnie jedynie call do tej procedury, nie zas inplementacja wait'a.

Tak wiec Twoj pokaz dalej mnie nie przekonuje, poprosze o implementacje takiego rozwiazania w ASM, badz kodzie

rdt
-
-
Posty:87
Rejestracja:20 sie 2003, o 18:03
Lokalizacja:100km od Wawy

Postautor: rdt » 17 mar 2007, o 06:27

Nie mam nic do dodania - posta napisalem bo szukam pomocy a nie po to żeby komuś coś udowadniać
(Choć to co napisałeś ma jakiś sens jednak znaczyłoby ze jest umieszczana zawsze jakas procedura odliczająca niezależnie czy używamy wait czy nie)
-nie wierzysz Twoja sprawa jak zmienisz środowisko to sam popatrz
skoro jednak nikt nie ma nic ciekawszego do dodania to temat uważam za zamknięty

radzio
Moderator
Moderator
Posty:967
Rejestracja:13 maja 2003, o 10:33
Lokalizacja:Sosnowiec
Kontaktowanie:

Postautor: radzio » 17 mar 2007, o 09:06

Mały eksperyment :

Kod: Zaznacz cały

do wait 1 loop end
Disasemblacja kodu (bo oczywiście Bascom skrzętnie ukrywa owoce swojej pracy):

Główna pętla programu wygląda następujaco :

Kod: Zaznacz cały

X0051: mov r0,#7fh;\ clr a ;| X0054: mov @r0,a ;| czyszczenie wewnętrznej pamięci ram djnz r0,X0054 ;/ mov sp,#21h ;inicjalizacja wskaźnika stosu mov 20h,#0 ; wyzerowanie bitu ERR X005d: mov r0,#1 ; czas opóźnienia acall X0039 ; wywołanie procedury opóźniającej ljmp X005d ; pętla nieskończona
Procedura opóźniająca znajduje się pod etykietą X0039 i wywołuje dwie dodatkowe procedury, co przedstawione jest poniżej :

Kod: Zaznacz cały

X002e: push acc mov a,#1bh X0032: dec a jnz X0032 pop acc nop ret ; X0039: mov a,#0c8h X003b: acall X0045 acall X0045 djnz acc,X003b djnz r0,X0039 ret ; X0045: push acc mov a,#19h X0049: acall X002e dec a jnz X0049 pop acc ret ;
Te cztery bajty to tylko instrukcje :

Kod: Zaznacz cały

X005d: mov r0,#1 ; czas opóźnienia acall X0039 ; wywołanie procedury opóźniającej
Ile bajtów zajmują procedury opóźniajace nie chce mi sie liczyć.

-> rdt, skompiluj program

Kod: Zaznacz cały

do wait 1 loop end
oraz

Kod: Zaznacz cały

do loop end
i wtedy porównaj rozmiar generowanego kodu. Bo na podstawie screenów które zamieściłeś takich wniosków wyciągnąć nie można z bardzo prostej przyczyny : w programie korzystasz z procedur obsługi LCD, a one też korzystają z opóźnień, tak więc dodanie instrukcji wait powoduje umieszczenie tylko ich wywołania bo ich kod jest używany przez procedury LCD.

rdt
-
-
Posty:87
Rejestracja:20 sie 2003, o 18:03
Lokalizacja:100km od Wawy

Postautor: rdt » 18 mar 2007, o 01:54

Radziu - zrobiłem jak mi pokazales - roznica to okolo 40 bajtów
teraz [ytanie brzmi - czy czytales pierwszy post - szuklam rozwiązania które mi zajmie mniej miejsca
jak moze ktos zauwazyl (albo i nie) napisalem ze szukam bardziej pamiecioszczednego rozwiazxania - kazde chetnie przyjme

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Postautor: pajaczek » 18 mar 2007, o 23:57

Radziu - zrobiłem jak mi pokazales - roznica to okolo 40 bajtów
W to juz jestem w stanie uwierzyc na slowo ;)

Rdt: jak widac Ty rowniez nie czytasz tego co sie Ci odpowiada. Wiec moze odpowiem tak:

Komorka mi siada... mozesz mi polecic jakas baterie, zeby miescila sie w miejsce oryginalnej, ale trzymala tak z rok ?? no, ostatecznie moze byc pol roku intensywnego korzystania.

[ Dodano: 20-03-2007, 10:37 ]
Wybaczcie post pod postem, ale chcialem odswiezyc temat, troche pomyslalem i jeszcze cos mi przyszlo do glowy, skoro tak koniecznie chcesz odchudzic program:

Moglbys odchudzic wywolanie waita do 2 bajtow, ale... no wlasnie, stosujac samo acall X0039, tyle ze wowczas podejmujesz spore (i moim zdaniem nigdy nie akceptowalne) ryzyko... jakie, ano takie ze nie masz wplywu na to ile to opoznienie bedzie trwalo, bo to bedzie odpowiednik wait 1 -- wait 256 (256 - to nie pomylka, dobrze ze wait przyjmuje tylko 1 bajt ;) ), a zalezec bedzie od aktualnej wartosc r0.

Czy Ci sie to oplaca, i ile tak naprawde masz tych wywolan by tak walczyc o kazde 2 bajty ?? ocen to sam.

Oczywiscie nie jest to sprzeczne z tym co pisalem wczesniej, nie da sie zrobic opoznienia w mniej niz 4 bajtach (nawet w 4 to z duzymi ograniczeniami), to jest jedynie wykozystanie faktu ze ten wait jest juz gdzies przez Ciebie (bascom) dolinkowanyę przez jakas inna biblioteke (LCD ??).
Ostatnio zmieniony 20 mar 2007, o 10:45 przez pajaczek, łącznie zmieniany 2 razy.

pajeczynka
-
-
Posty:2
Rejestracja:8 cze 2005, o 11:07
Lokalizacja:Winny Grod

Postautor: pajeczynka » 20 mar 2007, o 10:41

[ Dodano: 20-03-2007, 10:37 ]
Wybaczcie post pod postem, ale chcialem odswiezyc temat, troche pomyslalem i jeszcze cos mi przyszlo do glowy
;( post pod postem, a i tak nie odswiezylo tematu ;( no trudno.

szymel
-
-
Posty:212
Rejestracja:16 sty 2005, o 16:42
Lokalizacja:Włocławek

Postautor: szymel » 20 mar 2007, o 19:31

...Moglbys odchudzic wywolanie waita do 2 bajtow, ale... no wlasnie, stosujac samo acall X0039, tyle ze wowczas podejmujesz spore (i moim zdaniem nigdy nie akceptowalne) ryzyko... jakie, ano takie ze nie masz wplywu na to ile to opoznienie bedzie trwalo, bo to bedzie odpowiednik wait 1 -- wait 256 (256 - to nie pomylka, dobrze ze wait przyjmuje tylko 1 bajt ;) ), a zalezec bedzie od aktualnej wartosc r0. ...
Można "zużyć" 2 bajty i mieć pewność , że w R0 będzie 1 ;)
Warunek , wszystkie wywołania funkcji opóźniającej , muszą znajdować się na tej samej stronie pamięci , co owa funkcja/procedura.

Kod: Zaznacz cały

Do Gosub Jednasekunda ' zajętość pamięci programu , to 2 bajty dla gosub i ... Gosub Jednasekunda '... czas wykonania , to Wait 1 + 4 cykle maszynowe. Gosub Jednasekunda Gosub Jednasekunda Gosub Jednasekunda Gosub Jednasekunda Gosub Jednasekunda Loop Jednasekunda: Wait 1 Return
Bardziej skrócić się nie da :(

Piotrek

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Postautor: pajaczek » 20 mar 2007, o 23:35

Można "zużyć" 2 bajty i mieć pewność , że w R0 będzie 1 ;)
Warunek , wszystkie wywołania funkcji opóźniającej , muszą znajdować się na tej samej stronie pamięci , co owa funkcja/procedura.
No sprytnie sprytnie, tyle ze tez nie do konca :619: . 2 bajty zajmie gosub, zas wait 1 + return kolejne 6 :618:
A wiec calosc zajmie

Kod: Zaznacz cały

N*2 + 6 B = ------- N gdzie: N - ile razy uzyto opoznienia B - liczba bajtow przypadajaca na 1 wywolanie
:618:

A to jedynie asymptotycznie zbliza sie do 2B / kazde wywolanie.

rdt
-
-
Posty:87
Rejestracja:20 sie 2003, o 18:03
Lokalizacja:100km od Wawy

Postautor: rdt » 23 mar 2007, o 12:31

Ok - widzę ze tutaj nie ma zbytnio z czego zabrać
jeżeli więc możecie to powiedzcie mi inną rzecz - jak w asemblerze zabrać bajt spod jednego adresu i wsadzić pod drugi adres
odpowiedniki instrukcji peek i poke
może tutaj mi sie uda zaoszczędzić te parę bajtów

jeżeli w ogóle macie parę rad dotyczących optymalizacji kodu to chętnie posłucham

Dsmturbo
-
-
Posty:2
Rejestracja:23 mar 2007, o 14:14
Lokalizacja:Pisarzowice
Kontaktowanie:

Postautor: Dsmturbo » 23 mar 2007, o 14:40

Witam Chłopaki!
Bawiłem sie kiedyś bascomem i wiem że można zrobić wstawke asambler w programie. Wy tu próbujecie kożystać z poleceń bascoma a on tylko wykożystuje odpowiednie podprogramy napisane w asamblerze i zajmuje to kilka a nawet kilkadziesiąt bajtów. Wyszukaj sobie w helpie jak zrobić wstawkę asamblera...
z tego co pamietam to było chyba $asm
A potem wstaw taki kawałek programu napisanego najprościej w asamblerze:
MOV R2,#1
TIME:
DJNZ R0,$
DJNZ R1,TIME
DJNZ R2,TIME
programik realizuje odliczanie na rejestrach w pamieci ram dokładny czas tej operacji wynosi 0,524288 sekundy dla kwarcu 12MHz wszystkie instrukcje zajmują 8 bajtów i mniej sie nie da bo asambler to najprostszy jezyk programowania i nie wykożystuje podprogramów jak to robi bascom. Poszczególne rejestry są odliczane w kierunku zera jak skończy to program poleci dalej. Zeby zmienić czas trzeba załadowac do rejestrów odpowiednie wartości, w tym wypadku do R2 wprowadziłem wartość 1 czyli czas opóźnienia wynosi około 0,5s jej zwiekszysz tą wartość to czas proporcjonalnie sie zwiekszy. Na końcu tego programu musisz wstawić polecenie kończące wstawkę asamblera ale nie wiem jakie to jest, bedzie napisane w helpie do bacoma przy poleceniu wstawki. Aha żeby użyć tej wstawki musisz dokładnie wiedzieć z których rejestrów kożysta bacom ponieważ mogą one zostać zmienione przez ta wstawke gdyż ona odnosi sie do rejestrów o adresah 00h, 01h, 02h ( odpowiednio R0, R1, R2).
Powodzenia :629:

shadow82
-
-
Posty:12
Rejestracja:8 lis 2006, o 15:17
Lokalizacja:Trójmiasto
Kontaktowanie:

Postautor: shadow82 » 23 mar 2007, o 16:34

Kod: Zaznacz cały

Dim Variable1 As Byte Dim Variable2 As Byte $asm 'wersja na stałych mov r0, #&h30 'załaduj do wskaźnika r0 adres stałej = 30 hex (przykładowo) mov a, @r0 'przenieś do akumulatora (można w nim dowolnie tą daną zmienić) mov r0, #&h31 'załaduj do wskaźnika r0 adres docelowy (stała) mov @r0, a 'zapisz pod adresem r0 = 31 hex zmienną z akumulatora 'wersja na zmiennych mov r0, #{variable1} 'załaduj do wskaźnika adres zmiennej (NIE wartość, którą przechowuje) mov a, @r0 'przenieś do akumulatora (można w nim dowolnie tą daną zmienić) mov r0, #{variable2} 'załaduj do wskaźnika r0 adres docelowy (zmiennej Variable2) mov @r0, a 'zapisz pod adresem r0 zmienną z akumulatora $end Asm
Możesz przeprowadzić symulację i sprawdzić jak to działa i jednocześnie ile zajmuje miejsca w pamięci.
Co prawda "specjalistą" :) jestem bardziej od AVR'ów, ale w razie czego mogę pomóc w czymś jeszcze.

Wróć do „Projektowanie PCB, programy EDA, CAD, narzędziowe”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 21 gości