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.

Język C, przerwania w programie czy tylko za pomocą sleep?

nelik1987 31 Sie 2008 23:21 3963 10
  • #1 31 Sie 2008 23:21
    nelik1987

    Poziom 31  

    witam pisze prosty program do sterowania silnikiem krokowym i pomiędzy kolejnym adresowaniami porty LPT wstawiłem

    Code:
    system("sleep")
    ustawiłem jego wartoś na początku na 1 potem zmniejszałem no i jak wiadomo impulsy szły coraz szybciej ale w pewnym momencie zauwazyłem że silnik nie działa juz szybciej, podejrzeważ że jest to ograniczenie silnika, ale jak zakomentowałem linie odpowiedzialne za przerwania czyli wszytskie linie programu wykonały się bardzo szybko to silnik w ogóle nie ruszył bo tak szybko się impulsy zmieniały, dlaczego w takim raz wpisanie
    Code:
    system("sleep 0.00001")
    nie daje podobych efektów tylko działa tak samo jak
    Code:
    system("sleep 00.1")
    ???

    chciałem także podstawić za wartość czasu jaki system ma czekać zmienna ale kompilator GCC wywalił błąd :(

    W innych jezykach programowani były przyjemniejsze funkcje takie jak waitms czyli czekaj iles milisekund co było bardzo wygodne, jakie jeszcze mogę zastosowac funkcje?? Dodam ze pracuje na Linuks Slackware 12.1 tylko tryb tekstowy (konsola).

    0 10
  • #2 01 Wrz 2008 10:22
    kulmar
    Poziom 25  

    nelik1987 napisał:
    ... jak wiadomo impulsy szły coraz szybciej ale w pewnym momencie zauwazyłem że silnik nie działa juz szybciej, podejrzeważ że jest to ograniczenie silnika, ale jak zakomentowałem linie odpowiedzialne za przerwania czyli wszytskie linie programu wykonały się bardzo szybko to silnik w ogóle nie ruszył bo tak szybko się impulsy zmieniały


    Silników krokowych nie można wystartować od 0 do ich prędkości maksymalnej przez wygenerowanie sekwencji sterującej od razu z maksymalną częstotliwością. Silnik krokowy musi być rozpędzany od wartości minimalnej do wartości maksymalnej przez płynne zwiększanie częstotliwości impulsów podawanych przez sterownik.

    Pozdrawiam
    Mariusz

    0
  • #3 01 Wrz 2008 10:36
    tzok
    Moderator Samochody

    Zrób to tak, jak się to robi w uC - wstaw pustą pętlę for na n iteracji... możesz sobie w ten sposób napisać własną funkcję waitms, tylko musisz napisać funkcję skalującą działanie tej funkcji - obliczającą czas wykonania pętli for 0-1e6 /będzie różny dla różnych procesorów/ i na tej podstawie dobierającą stałą skalującą.

    0
  • #4 01 Wrz 2008 10:36
    fantom
    Poziom 31  

    A ty myslisz ze proces w systemie jest w stanie sie przelaczac tak szybko ? Niestety ale nie, dochodzi do minimalnego czasu w ktorym moze sie przelaczyc i koniec, nic dalej nie zrobisz.

    0
  • #5 01 Wrz 2008 10:55
    szelus
    Specjalista - Mikrokontrolery

    nelik1987 napisał:
    witam pisze prosty program do sterowania silnikiem krokowym i pomiędzy kolejnym adresowaniami porty LPT wstawiłem
    Code:
    system("sleep")


    Oryginalna metoda :)

    Cytat:

    chciałem także podstawić za wartość czasu jaki system ma czekać zmienna ale kompilator GCC wywalił błąd :(


    O Panie Boże, widzisz i nie grzmisz ;) A czy funkcja system() ma argumenty jak printf()? Trzeba najpierw utworzyć napis funkcją sprintf().

    Cytat:

    W innych jezykach programowani były przyjemniejsze funkcje takie jak waitms czyli czekaj iles milisekund co było bardzo wygodne, jakie jeszcze mogę zastosowac funkcje?? Dodam ze pracuje na Linuks Slackware 12.1 tylko tryb tekstowy (konsola).


    Zainteresuj się funkcją nanosleep(). I komendą man.

    0
  • #6 03 Wrz 2008 01:00
    Dr.Vee
    VIP Zasłużony dla elektroda

    Witam,

    Jak kolega nelik ma tego rodzaju problemy z funkcja system(), to nie chciałbym wiedzieć jak wygląda to "sterowanie LPT" - pewnie wstawki asemblerowe :D

    Jeśli chcesz mieć gwarantowane czasy rzędu 100us i krótsze, to powinieneś się zainteresować POSIXowymi timerami czasu rzeczywistego (jądro 2.6) - funkcja timer_create (3). Nie jestem pewien, czy funkcja nanosleep (3) korzysta z timerów real-time.

    Pozdrawiam,
    Dr.Vee

    0
  • #7 03 Wrz 2008 08:51
    fantom
    Poziom 31  

    timer_create bedzie tutaj dzialac lepiej gdyz po uplynieciu czasu jest wywolywana asynchronicznie wzgledem procesu funkcja zarejestrowana dla tego timera (jest wywolywana przez jadro z przestrzeni adresowej procesu) natomiast funkcja nanosleep niczego tu nie zmieni gdyz usypia ona proces na czas nie mniejszy niz ten wstawiony ale to nie oznacza ze proces obudzi sie po tym czasie (napewno nie obudzi sie po czasie krotszym). Polecam dokladniejsza lekture tej funkcji i wszystko bedzie wiadomo.

    EDIT: Po dokladniejszej analizie obslugi sygnalow w Linuxie stwierdzam ze sygnaly sa dostarczane do procesu dopiero gdy jest on wybrany przez jadro jako aktualny proces wiec takie rozwiazanie tez moze niewiele dac.

    0
  • #8 03 Wrz 2008 13:57
    riddyk
    Poziom 19  

    Z swojego doświadczenia wiem, że programowo na komputerze ( z Windowsem ) ciężko jest uzyskać częstotliwość większą niż 1Khz. Na to składa się kilka czynników, raz że w tle jest obsługiwanych więcej programów, więc procesor swój czas poświęca każdemu procesowi. Dwa funkcja może się nie wykonać do czasu następnego "przerwania".

    W Windowsie można pierwszy problem zaradzić ustawiając priorytet w real time, w menadżerem zadań,
    a z 2 to optymalizując kod.

    Myślę żeby sterować silnikiem krokowym należało by zrobić sterownik np na AtTinny z komunikacją po rs323, albo jak wolisz po LPT, i wtedy możesz mieć częstotliwość w kilkudziesięciu KHz ( zależy jaki procek do tego zaprzęgniesz i jak szybko porty potrafiły by zmieniać swój stan + tranzystory żeby nie obciążać port prądem z silnika.

    To nad czym się zastanawiasz jest naprawdę poważnym problemem jeżeli są ważne zależności czasowe, żeby na różnych komputerach działało prawie jednakowo. I chyba najoptymalniej było by zrobić to na zegarze sprzętowym. Odczytać czas, wykonać działanie, odczytać czas, i na podstawie tej różnicy czasowej przyjąć ile procesor ma czekać (np. przyjąć to w sposób funkcji liniowej, albo 2 stopnia).

    0
  • #9 03 Wrz 2008 14:57
    szelus
    Specjalista - Mikrokontrolery

    Kolega nelik nic nie pisał o wymaganiach do sterowania tym silnikiem, więc odnosiłem się tylko do jedynych konkretnych pytań, czyli dlaczego gcc wyrzuca błąd i jaka funkcja pozwala czekać krócej niż sekundę.

    Jeżeli natomiast chodzi o sterowanie silnikiem, to z praktycznego punktu widzenia, sterowanie z PC-ta bezpośrednio przez LPT jest takie bardziej bez sensu. Chyba, że ktoś chce się pobawić.

    Na upartego oczywiście można podnieść (w kernelu 2.6) priorytet procesu do poziomu real-time - wówczas taki proces otrzyma sterowanie natychmiast, gdy stanie się gotowy. Oczywiście jeżeli w tym czasie nie będzie aktywny proces o jeszcze wyższym priorytecie real-time.

    0
  • #10 18 Wrz 2008 16:29
    nelik1987

    Poziom 31  

    chciałem to rozwiązać za pomocą pętli która nic nie robi tylko się kreci poczyniłem pewne obliczenia i słabo to wyszło bo czasy poniżej 0,1 s są mierzone niedokładnie :( raz wykonanie tych pętli idzie komputerowi szybciej a raz wolniej, chociaż i tak jest to dużo lepsze od system (sleep) :D

    Czy jeszcze jakieś pomysły??

    0
  • #11 18 Wrz 2008 20:21
    Dr.Vee
    VIP Zasłużony dla elektroda

    Nelik,

    1) Pomysłów było już kilka - czytaj co inni już napisali powyżej,
    2) PC to nie mikrokontroler, nie zrobisz "pętli opóźniającej" bo w tym czasie OS może Twój proces wywłaszczyć x razy.

    Jedyne rozwiązanie: podnieść priorytet procesu (jak pisze szelus), użyć timer_create() i zaczekać na sygnał (jak pisze fantom).

    No chyba, że przesiądziesz się na system RealTime :)

    Pozdrawiam,
    Dr.Vee

    0