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

przepisywanie danych na port- asembler

bolek 19 Lut 2003 23:53 2795 10
  • #1 19 Lut 2003 23:53
    bolek
    Specjalista - oświetlenie sceniczne

    Mam delikatny problem z tym programikiem. Służy on do sterowania silnikiem krokowym. W zależności od wartości R4 resetowany jest odpowiedni pin procka. Jeśli ten program użyje razem z obsługą UARTa (przerwania) to mi wszystko skacze w maliny. Wiem że program jest zły, ale nie wiem gdzie. Jako tako steruje silnikiem, ale też zgłasza „lewe” przerwania dla RSa. w symulacji to działa, ale w praktyce nie.

    Poradzicie?... :(

    SILNIK: MOV DPTR, #KROK ;WSKAZ TABLICE Z INFORMACJAMI JAK ZALACZAC CEWKI SILNIKA
    MOV A, R4 ;PRZYGOTUJ DO ODEBRANIA DANYCH Z TABLICY (WZG. R4)
    MOVC A, @A+DPTR ;PRZEPISZ WARTOSC Z TABLICY DO ACC
    PUSH ACC ;ZACHOWAJ...
    MOV A, P3 ;SCIAGNIJ INFORMACJE Z PORTU
    ANL A, #11000011B ;ZAMASKUJ
    MOV B, A ;I PRZEPISZ DO B
    POP ACC ;ODSWIERZ ACC (WARTOSC Z TABLICY)
    ANL A, #00111100B ;MASKUJ... (:P)
    ORL A, B ;WYMIESZAJ
    MOV P3, A ;I WYSTAW NA PORT

    0 10
  • #2 20 Lut 2003 12:09
    Jaca
    Poziom 28  

    Czy w obsłudze przerwania z UARTa używasz A, Rx, rozkazów POP ACC i PUSH ACC, POP PSW, PUSH PSW ? Prawdopodobnie w programie głównym i procedurze obsługi przerwania używasz tych samych zestawów rejestrów (ACC, Rx)

    0
  • #3 20 Lut 2003 15:54
    bolek
    Specjalista - oświetlenie sceniczne

    W procedurze każdego pzrerwania odkladam znaczace rejestry na stos. trudno wuczuć co jest nie tak, "szopki" zaczynały sie w tedy gdy zostało zgłoszone przerwanie od RSa. na symulacji wskakiwał mi tylko do wektora tego przerwania i sie zatrzymywał. za to bardzo szybko zwiększał sie wskaźnik stosu, który "wjeżdzał" na pamięc... pierwszy raz widzałe że procek może tak namieszać 8O :roll:
    nie mniej jednak zmieniłem sposób sterowania silnikiem i problem natychmiast zniknął. no i bardzo mnie ciekawi co się stało że tak świrował!...

    W ZAŁĄCZNIKU OBA PODPROGRAMY

    0
  • #4 20 Lut 2003 20:29
    Marek81
    Poziom 19  

    Z załączonego przez Ciebie programu wynika, że cała procedura zawiera się w obsłudze przerwania od T0. Nie wiem natomiast jakie są rzeczywiste adresy tej procedury. Czy jest ona umieszczona pod adresem 000BH (wektor przerw. od T0) - jeżeli tak, to zachodzi na adres procedury obsługi RS'a - 0023H. To może być powodem dziwnego zachowania.
    Poza tym fizycznie zmieniasz stan pinów portu P3, a jak wiesz piny te mają podwójne znaczenie. I tak np. P3.0=RxD, a P3.1=TxD. A więc, jeśli zmienisz stan pinu P3.0 z 1 na 0, to procesor rozpocznie odczyt RS'a. No chyba że wcześniej zablokowałeś przerwania od RS'a.
    Jeśli powyższe nie ma racji, to podaj cały listing programu, najlepiej z adresami (org).

    Pozdrawiam.

    0
  • #5 20 Lut 2003 23:14
    bolek
    Specjalista - oświetlenie sceniczne

    caly listing w załączniku. co do "nachodzenia" na siebie funkcji portu to o tym pomyslałem i wydawało mi sie że ten sposób nie będzie bruździł w obsłudze portu. sposób w wystawianiem danych (dla silnika) na port miał zapewnić że zmeiniane są tylko 4 (środkowe) piny. reszta nie miała być zmieniana i w symulacji ten sposób sie sprawdził 8O- częsc ludzi steruje tak wyświetlacze LCD. druga sprawa to to że wszystko zaczeło sie sypac w momencie przyjecia przerwania od RSa ( chyba sie nie powtarzam)

    0
  • #6 21 Lut 2003 18:30
    Marek81
    Poziom 19  

    No cóż, muszę stwierdzić, że nie ma się do czego przyczepić. Program skompilowałem i poddałem symulacji krokowej. Wszystko działa - co prawda nie wnikałem w sposób obsługi silnika, ale stos zawsze wracał na wartość #6FH, po przerwaniach. Oczywiście nie ma mowy o nakładaniu się procedur, bo stosujesz skoki.
    Jednak, mój symulator nie testuje dokładnie RS'a - on przyjmuje, że już był odbiór i po zmianie zawartości SBUF, generuje przerwanie.
    Na Twoim miejscu umieściłbym linię: "CLR RI " na końcu obsługi przerwania, przed RETI, a nie na początku. Bo CLR RI , to zezwolenie na następny odbiór.
    Poza tym, tak na wszelki wypadek, upewniłbym się że przerwanie od RS'a jest faktycznie od odbioru, a nie od nadawania (mają ten sam wektor). W tym celu na początku obsługi IN_RS, napisałbym: JNB RI, i tu skok do RETI.
    Piszesz, że sterujesz sinikiem krokowym, może dla celów testowych, na razie, nie dołączaj go do układu. Zamiast silnika podłącz żaróweczki lub LED'y z oporami. Wyeliminuje to podejrzenia, że dziwne zachowanie wynika z zakłóceń wprowadzanych przez indukcyjności silnika.
    Napisz jakie masz efekty.

    Pozdrawiam.

    0
  • #7 22 Lut 2003 14:51
    bolek
    Specjalista - oświetlenie sceniczne

    przerwanie od "nadawania" znaku po RSie chyba nie ma szans wystąpić, wtedy w programie bym musiał miec: MOV SBUF, DANA.
    co do zapełniania sie stosu to działo sie tak jak chciałem przestawić priorytet przerwań. na początku programu napisałem MOV IP, #0 i nastepnie SETB PS, tak aby przerwanie od UARTU było najważniejsze. jednak coś tutaj pokiełbasiłem... :roll:

    kolejna dziwna sprawa to fakt iż przy standardowych ustawieniach priorytetów jako pierwsze (w moim programie) powinno być obsłużone przerwanie od T0- ma wyższy priorytet niż UART. tymczasem podczas symulacji, jesli zgłosiłem przerwanie od UART, procek zaczoł je obsługiwać, to zgłoszenia przerwania od T0 nie spowodowało skoku do procedury obsługi tego przerwania. procek skoczył tam dopiero jak zakończył obsługe UARTa. tak samo działo sie w drugą strone. wyglada to tak jak by priorytety tych przerwań były równorzędne... 8O :?: :?:

    jak to wyjaśnić?



    zaś załącznik... jest w nim wersja programu, która zapełnia stos. Jak Ktoś by chciał sobie postudiować

    0
  • #8 22 Lut 2003 17:16
    Marek81
    Poziom 19  

    Jeśli chcesz wyeliminować możliwość przerywania procedury obsługi np. RS'a, to najlepiej (ja tak zawsze stosuję) wpisz w pierwszej linii: CLR EA. Potem przed RETI: SETB EA. Timer nie przerwie tej procedury. Poczeka grzecznie na RETI i dopiero wtedy wykona swoją.
    Poza tym dobrze jest stosować krótkie procedury obsługi przerwań. W obsłudze np. od T0, przeładuj rejestry TL0 i TH0 i ustaw jakąś flagę np. SETB 1. A w pętli gównej czekaj na pojawienie się tej flagi: JB 1,skok. Jeżeli się pojawi, tzn. było przerwanie od T0, wykonasz jakąś procedurę i skasujesz flagę CLR 1. Chodzi o to, żeby być jak najkrócej w procedurach obsługi przerwań, szczególnie jeśli jest ich kilka i wzajemnie się przenikają (mogą wystąpić w tym samym czasie).
    Na koniec rada praktyczna. Jestem zwolennikiem "małych kroków". To znaczy, najpierw opracowuję jedną procedurę, np. obsługę RS'a i sprawdzam ją czy działa prawidłowo. Następnie dołączam następną i sprawdzam. I tak dalej. Dzięki temu mogę na bieżąco wyeliminować błędy.
    Jeżeli wszystko działa "od razu", to zły znak. Pewnie coś spieprzy się później.

    Pozdrawiam i życzę wytrwałości.

    0
  • #9 22 Lut 2003 17:21
    bolek
    Specjalista - oświetlenie sceniczne

    też tak robie, u mni program poowstaje poprzez sklejanie mniejszych- sprawdzonych wcześniej... cza przyznać że jest puźniej mniej sprawdzania.
    ale Marku uciekłeś od odpoweidzi na pytanie dotyczące "równosci priorytetów" posymuluj jeszcze troszkę ten programik i powiedz co o tym myślisz.

    (rónież) pozdrawiam!

    0
  • #10 22 Lut 2003 17:23
    Marek81
    Poziom 19  

    :arrow: Jaca
    Sorry, nie masz racji. Pozwól, że zacytuję z literatury:

    Rejestr IP służy do określenia poziomu poszczególnych przerwań. "0" lub "1" na poszczególnych pozycjach przyporządkowują dane przerwanie do poziomu odpowiednio 0 lub 1.
    PS - ustalanie poziomu priorytetu przerwania z układu transmisji szeregowej.
    PT1, PT0 - poziomy priorytetów przerwań z odpowiednich liczników.
    PX1, PX0 - poziomy priorytetów odpowiednich przerwań zewnętrznych.
    Podczas realizacji procedury obsługi przerwania poziomu 0 może nastąpić jej przerwanie przez procedurę obsługi przerwania o poziomie 1 - nie może jednak wystąpić sytuacja odwrotna. Nie może również wystąpić wzajemne przerywanie procedur obsługi przerwań z tego samego poziomu.
    Dodatkowo podczas realizacji programu może wystąpić jednoczesne zgłoszenie dwóch lub więcej przerwań o tym samym poziomie. Powoduje to wybranie do wykonania przez układ przerwań obsługi przerwania o najwyższym priorytecie według kolejności: INT0' (priorytet najwyższy), TF0, INT1', TF1, RI+TI (priorytet najniższy).


    :arrow: bolek
    Ten drugi program, w symulatorze, również działa prawidłowo. Tak jak napisałem wyżej, odnośnie priorytetów przerwań, w tym programie:
    - przerwanie od RS'a powoduje przerwanie obsługi przerwania od T0
    - przerwanie od T0 nie powoduje przerwania obsługi przerwania od RS'a.
    Tak wygląda teoria i tak działa to praktycznie w symulatorze. A dlaczego fizycznie nie chce działać? Nie wiem. W poniedziałek będę miał dostęp do książki - biblii o asemblerze '51, więc wszystko jeszcze raz sprawdzę. Być może coś jeszcze zostało przeoczone.

    Pozdrawiam.

    0
  • #11 25 Lut 2003 09:43
    krzysztof1
    Poziom 12  

    Proponowałbym trzymać się zasady, że obsuga przerwania (jakiegokolwiek) powinna być możliwie jaknajkrótsza. U Ciebie część obsługi przerwania od T0 mogłaby być realizowana w pętli głównej porgramu (u Ciebie w pętli głównej nic się nie robi!).

    0