logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak wyeliminować drgania styków w sterowniku silnika krokowego 89C2051?

Woojek 13 Cze 2005 22:57 3114 19
  • #1 1575439
    Woojek
    Poziom 11  
    Posty: 6
    Wykonałem sterownik do silnika krokowego na uP 89C2051 i do portów wejściowych uP zamontowałem switche. Problem w tym, że trzeba zlikwidować drgania styków. Pisze w aseblerze i nie wiem jak to napisać. Jeżeli ktoś będzie wiedział prosiłbym o napisanie przykładowego programu dla jednego przycisku (naciśnięcie przycisku powoduje pojawienie sie masy na porcie)
  • #2 1575516
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Uniwersalny sposób postepowania dla wszystkich mikrokontrolerów (note especially for jj ;)) :
    Masz w zapasie nieużywany timer liczący w dół (do 0) ? Przy każdym wciśnięciu ustawiasz timerek na jakąś wartość opóźnienia, np. 150ms. Z chwilą gdy timer osiągnie zero, przestaje liczyć. Tak więc przed sprawdzeniem czy przycisk naciśnięto, sprawdzasz wartość timera i sprawdzasz dalej przycisk, tylko, gdy timer jest wyzerowany. Ostatecznie można zaimplementować licznik programowy w procedurze przerwania od timera, umieszczając wartość takiego licznika w RAM.
    Pozdrawiam, Light'I
  • #3 1576188
    jj
    Poziom 19  
    Posty: 145
    Pomógł: 42
    Woojek napisał:
    Wykonałem sterownik do silnika krokowego na uP 89C2051 (...)


    Light'I napisał:
    Masz w zapacie nieużywany timer liczący w dół (do 0) ? (...)


    A czy w 89C2051 jest jakiś timer liczący w dół (a może nie doczytałem datasheet-a :wink:)?

    Pozdrawiam, jj.
  • #4 1576229
    fantom
    Poziom 31  
    Posty: 1649
    Pomógł: 108
    Ocena: 42
    A czy musi byc liczacy w dol ? Moze byc wszystko co pozwoli odmierzyc okreslony czas.Najlepiej zrobic sobie rejestr przesuwny w ktorym na poczatek wpychasz stan danego przycisku i patrzysz czy uzyskales stabilne 0 czy stabilna 1.
  • #5 1576246
    u24
    Poziom 14  
    Posty: 65
    Pomógł: 2
    Ocena: 3
    a zwykla petelka w petelce nie da rady? - musisz odczekac kilka ms, zalezy czy masz jakis filterek na wejsciu.
  • #6 1576351
    diag
    Poziom 29  
    Posty: 1401
    Pomógł: 45
    Ocena: 209
    Najczęstsze rozwiazanie sprzetowe to kondensator 100nF, jeżeli korzystasz z pul-up portu.
  • #7 1576381
    u24
    Poziom 14  
    Posty: 65
    Pomógł: 2
    Ocena: 3
    ;-) - drogi diagu a co jesli nie kozystasz z pull-up?? czy najczeszcze rozwiazanie sprzetowe to nadal 100nF... czy tylko pull-up ma wplyw na stala RC??
    Panowie pozbadzmy sie mentalnosci szewca, to sie da policzyc!
  • #8 1576635
    diag
    Poziom 29  
    Posty: 1401
    Pomógł: 45
    Ocena: 209
    No to licz.
  • #9 1576929
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    jj napisał:
    A czy w 89C2051 jest jakiś timer liczący w dół (a może nie doczytałem datasheet-a :wink:)?
    Moja wypowiedź jest uniwersalna, nie wnikałem w cyferki i literki na obudowie, można ją zastosować do dowolnego mikrokontrolera. Wyrwałeś z kontekstu, bo dalej dodałem, co zrobić w wypadku, gdzy takiego licznika nie ma, lub jest zajęty. Czytaj ze zrozumieniem. Poprawka dotyczy słowa "zapacie" -> "zapasie", żeby nie było niedomówień... ;)
    Co do pozostałych sposobów :
    - Wszelkie pętelki są trudniejsze do ogarnięcia czasowo, ale jak kto woli. Przy zmianie oscylatora zmieniają się czasy i żeby wszystko się zgadzało, trzeba nop-ów nawtykać kazdej procedyrze oddzielnie... Uważam, ze jedyna prawidłowa pętla to pętla główna, pozostałe to jest marnotrawienie MIPS-ów, które często się przydają do wykonania innych zadań w miedzyczasie. Teraz praktycznie każdy procesorek ma układ czasowy i to z wywołaniem przerwania.
    - Kondensator z rezystorem - owszem, ale tylko na wejściach Shmitta, w pozostałych wypadkach pewien przedział napięć jest niedopuszczalny, gdyż powoduje zwiększony pobór mocy. No i po to się używa mikrokontrolera, aby zminimalizować ilość potrzebnych elementów, w końcu od czego jest program... ;)
  • #10 1577343
    Woojek
    Poziom 11  
    Posty: 6
    Wielkie dzięki, ale jeśli chodzi o drgania to potrzebuje rozwiązania programowego, a nie sprzętowego. W programie który chce napisać będzie 5 przycisków, które będą sterować odpowiednio silnikiem krokowym. Program ma rozpoznawać który przycisk został naciśniety i będzie eliminować problem drgania styków. Problem polega na tym, że nie wiem jak to napisać w asemblerze.
  • #11 1577413
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Nie opisałeś dokładnie sposobu obsługi, więc trudno o szczegółową odpowiedź... Przyciski obsługiwane niezależnie mają oddzielne liczniki, a zależnie - wspólne. Przy takiej ilości to pozostaje obsługa liczników programowych w przerwaniu timera. Reszta procedury w petli głównej sprawdzająca po kolei stan liczników i jeśli są wyzerowane dla danego przycisku, to sprawdza ona stan tego przycisku. Jak nie jest wciśnięty żaden przycisk, to zawsze się znajdzie coś innego do roboty...
  • #12 1577539
    Woojek
    Poziom 11  
    Posty: 6
    Z załączniku umieściłem dokładny schemat układu, który wykonałem. Przyciski zamontowane są odpowiedzialne za poszczególne ruchy silnika krokowego (przycisk ma reagować na zbocze opadające). P1- prawo 1, L1 - lewo 1, P10 - prawo 10, L10 - lewo 10. Nie znam się dobrze na asemblerze dlatego wdzięczny będę o podanie przykładu jak rozpoznawać, który switch został włączony oraz odrazu programowo wyeliminować drgania styków.
    Załączniki:
    • Jak wyeliminować drgania styków w sterowniku silnika krokowego 89C2051? step motor.jpg (198.16 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #13 1578080
    michal10022
    Poziom 11  
    Posty: 25
    Pomógł: 1
    rozumiem że odczytujesz stan zera po styknięciu z masą więc ja bym zrobił tak
    wciskasz a procedurka zaczyna działać (np; port p1.6)
    jnc p1.6,czekaj
    ljmp nie_wcisnienty
    czekaj:
    mov b,#100
    ok_50_ms:
    mov a,#220
    djnz acc,$
    djnz b,ok_50_ms
    jnc p1.6,dalej
    dalej:
    -
    -
    nie_wcisnienty:


    po wciśnięciu klawisza czyli zczytaniu pierwszego zakłucenia wywołującego zero na wejściu procek czeka około 50 mili s. i sprawdza jeszcze raz

    Dodano po 6 [minuty]:

    a i ściągnołem ten twuj projekt
    sterowania silnikiem krok ,nieobraz się ale bardziej skolmplikowany to on niemoże już być
    ja sterowałem zwykłyumi tranzystorami npn w układzie inwertera lub jak kto woli (oe)
    jak by co to wal na meila hwdp-22(_at_)wp.pl
  • #14 1578105
    GienekS
    Poziom 32  
    Posty: 1971
    Pomógł: 139
    Ocena: 15
    To jest jedno z moich rozwiązań klawiatury:
    ;Procedura obslugi klawiatury
    ;w R2 licznik klawisza
    ;w OLDK stara wartosc klawisza
    ; OLDK=R7
    GET_KEY:
    	setb	P3.3
    	acall	ACK
    	acall	PIKER
    	mov	C,ACC.3	;in TxON
    	mov	P3.2,C	;out TxON
    	ACALL	KEY
    	MOV	A,R2
    	JZ	NIE_K	;brak klawisza
    	acall	KOD_K
    	CJNE	A,7,JEST_K
    NIE_K:	MOV	R7,A
    	AJMP	GET_KEY
    JEST_K:	MOV	R7,A
    	acall	KLIK
    	push	acc
    	acall	CLS
    	pop	acc
    	clr	STAT.7	;bit urzytkownika
    	clr	STAT.6	;bit dla gruchy
    	cjne	a,#12,JEST_1
    	ret
    JEST_1:	clr	PSW.5
    	RET
    ;
    KEY:	ORL	P1,#7fh
    	MOV	R2,#0
    	XRL	P1,#1
    	ACALL	LINIA
    	JC	GK	;jest klaw. w linii
    	XRL	P1,#3
    	ACALL	LINIA
    	JC	GK
    	XRL	P1,#6
    	ACALL	LINIA
    	JC	GK
    	MOV	R2,#0
    GK:	RET
    ;
    LINIA:	MOV	R1,#4
    	MOV	A,P1
    	CPL	A
    	rlc	A
    L7:	INC	R2
    	rlc	A
    	JC	GK	;jest klawisz
    	DJNZ	R1,L7
    	RET
    ;Tabela KODow Klawiatury
    KOD_K:	movc	a,@a+PC
    	ret
    	db	10,7,4,1,11,8,5,2,12,9,6,3
    ;dla klawiatury telefonicznej 10 zamienia sie z 12
    
  • #15 1578499
    jj
    Poziom 19  
    Posty: 145
    Pomógł: 42
    Light'I napisał:
    jj napisał:
    A czy w 89C2051 jest jakiś timer liczący w dół (a może nie doczytałem datasheet-a :wink:)?
    Moja wypowiedź jest uniwersalna, nie wnikałem w cyferki i literki na obudowie, można ją zastosować do dowolnego mikrokontrolera. Wyrwałeś z kontekstu, bo dalej dodałem, co zrobić w wypadku, gdzy takiego licznika nie ma, lub jest zajęty. Czytaj ze zrozumieniem. Poprawka dotyczy słowa "zapacie" -> "zapasie", żeby nie było niedomówień... ;)
    (...)


    Ależ czytam ze zrozumieniem. Kolega Woojek podał konkretny typ mikrokontrolera i zapewne oczekiwał pomocy w rozwiązaniu problemu właśnie dla niego. Czy wspomniałeś gdzieś, że Twoja wypowiedź jest uniwersalna? Z tekstu to nie wynika, a "moja wróżka ma dzisiaj wolne" :wink:
    A co do wyrwania z kontekstu - czy nie dodałem na końcu cytatu magicznych znaczków (...)? Myślę, że czytający ze zrozumieniem wiedzą, co one znaczą.
  • #16 1578840
    Woojek
    Poziom 11  
    Posty: 6
    michal10022 napisał:

    a i ściągnołem ten twuj projekt
    sterowania silnikiem krok ,nieobraz się ale bardziej skolmplikowany to on niemoże już być
    ja sterowałem zwykłyumi tranzystorami npn w układzie inwertera lub jak kto woli (oe)
    jak by co to wal na meila hwdp-22(_at_)wp.pl


    Wielkie dzięki, wykorzystam i po testuje ten przykład. Co do złożoności projektu, potrzebny jest uP, ponieważ w projekcje jest przywidziana łączność z komputerem. Sterownik silnika ma współpracować i wykonywać polecenia z interfejsu napisanego w Borland C++Builder .
  • #17 1578876
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    Ajamamototakie ;)
    Wrzucam cały główny program + include, bo nie chce mi się go ciąć, ot leń ze mnie i tyle ;)
    Przy okazji w ramach gratisu"wieczny" kalendarz na lata 2000-2255 obliczający dzień tygodnia (procedura calc_weekday) w zdaję się mniej niż 100 cykli, a nie jakieś badziewie z AVT, które potrzebuje na to kilku sekund(!). No i jeszcze pare pierdółek - w sumie to jest część wypasionego zegara LCD z kontrolerem PLL do nadajnika.

    Tabuacja jest na 4. W ramach mojego "zboczenia" lingwistycznego wszystkie komentarze są po angielsku ;)

    Obsługa klawiatury jest mieszana: wszystko, co jest związane z odmierzaniem czasu jest w przerwaniu timera0 (zaczyna się od etykiety noclock)
    Cała "logika" jest w głównej pętli programu zaraz na początku (etykieta main)

    Najpierw do zmiennej buttons ładowane są stany odczytane z linii portu (aliasy BLEFT, BRIGHT itd. to właśnie linie portów odpowiadające poszczególnym przyciskom) Taki sposób odczytu czyni program bardzo uniwersalnym - można w tym miejscu wstawić dowolną procedurę odczytującą stany klawiszy.

    Dalej jest cała logika - na podstawie stanów przycisków i pozostałych zmiennych odnoszących się do klawiatury "składana" jest zmienna bexec, określająca, które funkcje należy wykonać (specjalnie napisałem "które", bo program radzi sobie z dowolną ilością klawiszy wciśniętych naraz). Poszczególne bity zmiennej bexec odpowiadają funkcjom przyporządkowanym do klawiszy. I tak - jeżeli klawiszowi odpowiada bit 3 w zmiennej buttons, to po jego naciśnięciu zostanie ustawiony bit 3 w zmiennej bexec.

    Na podstawie zawartości bexec wywoływane są procedury obsługi poszczególnych klawiszy.

    Algorytm jest dość zawiły, ale jakoś pokrótce postaram się opisać przynajmniej jak działa z punktu widzenia użytkownika, w rzeczywistości wygląda to nieco inaczej.

    Przede wszstkim - każdemy przyciskowi z osobna można przypisać funkcję autopowtarzania (zmienna bautorep)
    Przyciski zachowują się tak jak klawiatura komputera - jeżeli dla przycisku uaktywniona jest funkcja autopowtarzania, to po pierwszym naciśnięciu natychmiast wywoływana jest odpowiadająca mu funkcja, potem przycisk pozostaje nieaktywny przez czas określony przez stałą iclock2d (jednostką jest 10ms, ale można zmienić). Po upłynięciu tego czasu, jeżeli przycisk jest wciąż wciśnięty, funkcja wywoływana jest ponownie. Od tej pory wywoływanie powtarza cię co okres wyznaczony przez stałą iclock2r (jednostka 10ms), aż do momentu, gdy klawisz zostanie zwolniony.
    Dla klawiszy, które nie mają funkcji autopowtarzania procedura wywoływana jest tylko raz po naciśnięciu klawisza i przytrzymywanie go nie pomaga ;)
    Jeżeli aktualnie powtarzany jest jakiś klawisz (autopowtarzanie) i wciśnięty zostanie kolejny, to ten jeden raz opóżnienie autopowtarzania dla przytrzymywanego klawisza będzie równe iclock2d zamiast iclock2r. takie uproszczenie w niczym nie przeszkadza, a i program nie musi być dzięki temu niepotrzebnie rozbudowany.
    W momencie, gdy klawisz zostaje zwolniony rozpoczyna się odmierzanie czasu "martwego" (stała iclock0 jednostka 0.25ms, domyślnie 40ms), przez który przycisk nie reaguje na naciskanie.
    Wszystkie właściwości klawiatury można modyfikować "w locie", dotyczy to zarówno funkcji autopowtarzania, jak i czasów opóźnień, z tym że te ostatnie należało by w tedy zapisywać jako zmienne, a nie stałe.

    Całość jest tak zorganizowana, że praca programu nie jest przerywana, całe odmierzanie czasu odbywa się w tle.
    No i zastosowany algorytm eliminuje "za jednym zamachem" drgania powstałe zarówno przy naciskaniu, jak i zwalnianiu klawisza.
    W tej wersji obsługiwane jest maksymalnie 8 klawiszy, dodanie kolejnych sprowadza się do powtórzenia kilka razy (po jednym na każde 8 klawiszy) tego samego kodu (a właściwie tylko "logiki" i małej modyfikacji przerwania)

    Żeby wykorzystać procedurę we własnym programie trzeba wyciąć wszystko od etykiety main do komentarza "Clock and date incrementing", oraz wszystkie fragmenty, do których kod ten sie odwołuje (przerwanie!). Ważna jest też procedura inicjalizująca zmienne.

    Przerwanie wywoływane jest co 250µs, można z powodzeniem użyć innej częstotliwości, trzeba wtedy tylko dobrać odpowiednio stałe opóźnień.

    The Koniec
    Załączniki:
    • zegar_synt_defs.incl.txt (12.31 KB) Musisz być zalogowany, aby pobrać ten załącznik.
    • zegar_synt.asm.txt (67.06 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #18 1580211
    Woojek
    Poziom 11  
    Posty: 6
    Układ 89C2051 ma 2 porty (P1,p3) wejścia/wyjścia. Z projektu, który przedstawiłem wyżej switch-e załączyłem do portu p3, a diody do portu wyjściowego. Z dokumentacji układu jest podane, że obydwa porty są I/0. Czy ktoś wie jak ustawić programowo w asemblerze, alby port P3 był portem wejściowym, a port P1 wyjściowym??

    Czy ktoś zna jakiś program, ktory jest dobrym symulatorem oraz by była możliwość pisania w nim programu w asemblerze??
  • #20 1582941
    Woojek
    Poziom 11  
    Posty: 6
    Dzięki wszystkim za odpowiedz na temat eliminacji problemu eliminacji styków drgań.
    Przy pisaniu dalszej części programu pojawił się problem:
    Jak wiadomo silnik krokowy można sterować 3 typami pracy. Pisze teraz program, który będzie umożliwiał sterowanie falowe (A -> B -> Not A -> Not B). Układzie, który przedstawiłem wyżej są 5 przycisków (port: P3.2 – obrót 1 w prawo, P3.3 – obrót 1 w lewo, P3.4 – obrót 10 w prawo, P3.5 – obrót 10 w lewo, P3.7 – zmiana szybkości obrotu silnika 250ms, 1s). Po naciśnięciu odpowiedniego przycisku ustawiam w dowolnej komórce pamięci wartość ilości kroków jak ma wykonać silnik. Chciałbym napisać podprogram, który będzie zaczytywał wartość komórki pamięci i odpowiednio wykonywał sekwencje obrotu silnika. Nie wiem jak to napisać i jak ktoś będzie wiedział to będę wdzięczny za podpowiedzi albo przykłady.

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy eliminacji drgań styków (debounce) w sterowniku silnika krokowego opartego na mikrokontrolerze 89C2051, programowanym w asemblerze. Problem polega na stabilnym wykrywaniu naciśnięcia przycisków podłączonych do portów wejściowych uP, gdzie naciśnięcie powoduje pojawienie się stanu niskiego (masa) na porcie. Proponowane rozwiązania obejmują zarówno sprzętowe, jak kondensator 100nF w układzie z rezystorem pull-up, jak i programowe metody eliminacji drgań. Wśród programowych metod rekomendowano wykorzystanie timerów mikrokontrolera do odmierzania opóźnienia (np. 150 ms) po wykryciu zmiany stanu przycisku, a następnie ponowne sprawdzenie stanu, co pozwala potwierdzić stabilność sygnału. Alternatywnie sugerowano implementację rejestru przesuwnego do monitorowania stabilności sygnału lub prostą pętlę opóźniającą w asemblerze. Przykładowy kod w asemblerze pokazuje odczyt stanu przycisku, wprowadzenie opóźnienia około 50 ms i ponowne sprawdzenie stanu, co eliminuje fałszywe wyzwolenia. Dyskutowano także o konfiguracji portów 89C2051, gdzie porty P1 i P3 mogą być używane jako wejścia lub wyjścia, a piny wejściowe pozostawia się w stanie wysokim (pull-up). W dalszej części rozmowy pojawiły się pytania o implementację sterowania falowego silnikiem krokowym (sekwencja A -> B -> Not A -> Not B) oraz o programowe odczytywanie wartości z pamięci i wykonywanie kroków silnika. Wspomniano również o integracji sterownika z komputerem poprzez interfejs napisany w Borland C++Builder. Dyskusja zawiera fragmenty kodów asemblerowych oraz sugestie dotyczące obsługi przerwań timerów i logiki w pętli głównej programu.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA