Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Sterowanie silnikiem krokowym- ugrzązłem (ale jest postęp)

janbernat 09 Feb 2010 20:58 3344 19
  • #1
    janbernat
    Level 38  
    Code:

    'Program do sterowania małych silników krokowych za pomocą ATMega8 i układu L6219 lub LB1845
    'sterowanie ćwierćkrokowe, zasilanie 30V


    $regfile "m168def.dat"
    $crystal = 4915200

    '********* Konfiguracja wyświetlacza *********
    $lib "Lcd4busy.lib"
    Const _lcdport = Portd
    Const _lcdddr = Ddrd
    Const _lcdin = Pind
    Const _lcd_e = 1
    Const _lcd_rw = 2
    Const _lcd_rs = 3
    Config Lcd = 20 * 4

    '*********** Konfiguracja wyjść do sterowania L6219 ************
    Config Portc = Output
    Ph1 Alias Portc.0             'kierunek przepływu prądu w uzwojeniu Ph1
    Ph2 Alias Portc.1             'kierunek przepływu prądu w uzwojeniu Ph2
    I01 Alias Portc.2             'napięcie dostarczane do uzwojeń- 1 , 2/3 lub 1/3 Imax
    I11 Alias Portc.3
    I02 Alias Portc.4
    I12 Alias Portc.5
    Reset Ph1                     ' na początek ustawiamy krok 0
    Reset I01
    Reset I11
    Set I02
    Set I12
    Reset Ph2

    '********** PortB jako wejście z podciąganiem ***************
    Config Portb = Input
    Set Portb

    '********** ustawienie przerwań ****************
    sei

    Config Timer0 = Timer , Prescale = 8       ' teraz da ok. 0.417us- ale może skrócić
    'Config Timer2 = Timer , Prescale = 1024
    Enable Ovf0
    On Ovf0 Step_delay





    Dim Kier As Byte
    Dim Temp0 As Byte
    Dim Opoznienie_odczytu As Byte
    Dim Stan As Byte
    Dim Kroki As Word
    Dim Liczba_powtorzen As Byte
    Dim Kat As Single
    Dim Liczniczek As Byte
    Liczniczek = 100
    Dim U1 As Byte
    U1 = 4
    Dim Up As Byte
    Dim Ul As Byte
    Dim Us As Byte
    Up = 255
    Ul = 255
    Ul = 255
    Dim Rampa As Word
    Rampa = 65000

    Dim Koniec As Word
    Koniec = 1000



    Dim Next_step As Byte
    Next_step = 0
    Dim Flaga As Byte
    Flaga = 0
    Dim Liczba_krokow As Word
    Liczba_krokow = 0             'Tu mogę wpisać 1000- i tak nie reaguje
    Kier = 0

    Cls
    Cursor Off
    Locate 1 , 1
    Lcd "ustal kierunek "



    Do

       If Flaga = 1 Then          'gdy jest przerwanie od Timer0- co 237us
         If Pinb.0 = 0 Then       'i jest wciśnięty przycisk PIND.2- ustawianie kierunku jednym przyciskiem
             Incr Opoznienie_odczytu       'no bo przycisk ma drgania dłużej niż 237us- niech zwiększy
                                            'to sprawdzanie powtórne do 17ms

             If Opoznienie_odczytu >= 70 Then       'dajmy mu na wygaszenie drgań 17ms

                If Temp0 = 0 Then ' i jest zezwolenie na zmianę stanu
                   Gosub Ustawianie
                   Temp0 = 1      ' zablokuj zezwolenie na zmianę stanu
                End If

                Opoznienie_odczytu = 0       'Jak już ustawił kierunek to pozwolimy mu liczyć od początku-
                                              'po powtórnym naciśnięciu PIND.2
              End If

          Else
             Temp0 = 0            'zezwalaj na zmiany
             Opoznienie_odczytu = 0
          End If

          If Kier = 1 Then
             Gosub Kier_prawo
          End If

          If Kier = 2 Or Kier = 0 Then
             Gosub Kier_stop
          End If

          If Kier = 3 Then
             Gosub Kier_lewo
          End If

          Flaga = 0


       End If
          Debounce Pinb.3 , 0 , Ustaw_liczba_krokow

    Loop
    End


    Step_delay:                   'ten timer określa szybkość z jaką szybkością kręci się silnik- teraz ok0.25ms/ impuls
       Timer0 = 60                '110     'no to skracamy- ten silnik się jeszcze kręci- ale na jakimś innym moze to trzeba zmienić
                         'tu jest ok.237us obliczone a 248us zmierzone- procesor jednak coś wolno liczy
       Flaga = 1


          Incr Next_step          'sterowanie 1/8 kroku- 16 stanów
             If Next_step >= 16 Then
                Next_step = 0
          End If


    Return


    Ustawianie:



          Select Case Kier
             Case 0
               Locate 1 , 1
               Lcd "kierunek- lewo " ; Kier
             Case 1
               Locate 1 , 1
               Lcd "kierunek- stop " ; Kier
             Case 2
               Locate 1 , 1
               Lcd "kierunek- praw " ; Kier
             Case 3
               Locate 1 , 1
               Lcd "kierunek- stop " ; Kier

           End Select

        Incr Kier
         If Kier >= 4 Then
           Kier = 0
         End If


    Return

    Kier_prawo:                   'Sterowanie układu L6219 lub LB1845- w przypadku sterowania STEP, DIR ten fragment należy uprościć

     For Kroki = 0 To Liczba_krokow
        Select Case Next_step

             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
             Case 1
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 2
                Reset Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 3
                Reset Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 4
                Set Ph1 : Set I11 : Set I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 5
                Set Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 6
                Set Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 7
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 8
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
             Case 9
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
             Case 10
                Set Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 11
                Set Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 12
                Reset Ph1 : Set I11 : Set I01 : Set Ph2 : Reset I12 : Reset I02
             Case 13
                Reset Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 14
                Reset Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02


          End Select

      Next

    Return

    Kier_lewo:                    ' j.w.

     For Kroki = 0 To Liczba_krokow
          Select Case Next_step

             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
             Case 1
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
             Case 2
                Reset Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 3
                Reset Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 4
                Set Ph1 : Set I11 : Set I01 : Set Ph2 : Reset I12 : Reset I02
             Case 5
                Set Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 6
                Set Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 7
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
             Case 8
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
             Case 9
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 10
                Set Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 11
                Set Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 12
                Reset Ph1 : Set I11 : Set I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 13
                Reset Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 14
                Reset Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02


          End Select
      Next


    Return

    Kier_stop:                    'stop ma zachować aktualne położenie wirnika
    Stan = Pinc

    Return

    Ustaw_liczba_krokow:          'Tu jest ustawianie- czas bez znaczenia i wszystkie paskudy typu wait czy debouce dozwolone

    Cls
    Lcd "liczba krokow"
    Liczba_krokow = 1
    Do

    Waitus 500
    Decr U1
      If Pinb.1 = 1 Then
       Liczniczek = 100
      End If

       If Pinb.1 = 0 Then
        If U1 = 0 Then
          U1 = Liczniczek
          Decr Liczniczek
          If Liczniczek < 2 Then Liczniczek = 2
              If Liczba_krokow <= 16000 Then
                 Kat = Liczba_krokow * 0.029296875
              End If

              If Liczba_krokow >= 16000 Then
                Liczba_krokow = 16000
              End If
                Incr Liczba_krokow

                Lowerline
                Lcd " ->  " ; Liczba_krokow ; "      "
                Thirdline
                Lcd "Kat " ; Kat ; "        "

          End If
       End If


       If Pinb.2 = 1 Then
        Liczniczek = 100
       End If

        If Pinb.2 = 0 Then
         If U1 = 0 Then
           U1 = Liczniczek

            Decr Liczniczek
          If Liczniczek < 2 Then Liczniczek = 2
            If Liczba_krokow <= 16000 Then
              Kat = Liczba_krokow * 0.029296875
            End If

            If Liczba_krokow <= 1 Then
              Liczba_krokow = 1
            End If
              Decr Liczba_krokow

              Lowerline
              Lcd " <-  " ; Liczba_krokow ; "      "
              Thirdline
              Lcd "Kat " ; Kat ; "        "

         End If
        End If




        If Pinb.4 = 0 Then Exit Do
    Loop
    Return

    No i tak- jak przekazać liczba_kroków do kier_prawo/lewo aby program wykonał określoną liczbę kroków.
    I jak zrobić żeby silnik startował od określonego położenia- 1/4 kroku-16 stanów po zatrzymaniu.
  • Helpful post
    #2
    mirekk36
    Level 42  
    Witam,

    Hmmm nie dość, że strasznie rozbudowany fragment kodu, który ciężko tak wprost przeanalizować to jeszcze nie do końca rozumiem pytań bo:

    1. Pytasz jak przekazać liczba_krokow do kier_prawo/lewo

    a przecież masz tam zmienną Liczba_krokow w pętli

    For Kroki = 0 To Liczba_krokow

    czyli przed wywołaniem tej procedury wpisujesz liczba_krokow i już - chyba że czegoś nie rozumiem - bo przecież zdaje się tak robisz właśnie

    No a na 2 pytanie, żeby odpowiedzieć to już by trzeba chyba było nieźle posiedzieć nad tym kodem i domyśleć się dokładnie wszystkiego co i jak ma działać - a kto to zrobi ?

    Może na jakimś mniejszym wycinku kodu - bardziej sprecyzuj problemy hmmm ?
  • #3
    janbernat
    Level 38  
    No to tak- fragmenty kodu do sterowania silnika prawo/lewo/stop działają.
    Można na to nie zwracać zbytniej uwagi- to sprzęt.
    Można je zamienić na proste step/dir-gdyby zastosować inny sterownik:D
    Mam for- to-next- ale to jakoś nie działa.
    Jak wpiszę w początkowych ustawieniach liczba_kroków= 1000 to itak się kręci stale.
    Jak wpiszę w pętli for- to 1000 wprost- też się kręci w kółko.
    Ale jak wpiszę w pętli wait to kręci się "skokami".
    Podejrzewam że po return jak wracam do głównego programu to wraca do podprogramu z powrotem.
    No i nie wiem jak to kontrolować.

    a co do drugiego punktu- masz rację muszę nad tym jeszcze posiedzieć.
    W jakiejś zmiennej muszę zapamiętać jeden z 16 stanów składających się na 1 krok aby po stop zapamiętać i potem zacząć kręcić silnikiem od tego a nie innego położenia.
    No i co z tego że rozumiem sprzęt- jak programista ze mnie jak z koziej ...trąba.
  • Helpful post
    #4
    hose2
    Level 16  
    Witam
    janbernat wrote:
    Code:

    Kier_prawo:                   'Sterowanie układu L6219 lub LB1845- w przypadku sterowania STEP, DIR ten fragment należy uprościć

     For Kroki = 0 To Liczba_krokow
        Select Case Next_step
    ...
          End Select

      Next

    Return
    Code:

    Kier_lewo:                    ' j.w.

     For Kroki = 0 To Liczba_krokow
          Select Case Next_step
    ...
          End Select
      Next


    Return


    W tych podprogramach nie wywołujesz LICZBA_KROKOW+1 razy kroku silnika,
    bo wewnątrz pętli nie zmienia się NEXT_STEP (w pewnym sensie faza napięcia
    podawanego na cewki silnika) - po prostu wiele razy wystawiasz ten sam stan
    na porty. Obsługa zmiennej LICZBA_KROKOW może być w pętli głównej programu -
    wywołujesz podprogram KIER_LEWO lub KIER_PRAWO jednocześnie zmniejszając jej
    zawartość. Gdy osiągnie wartość zero przestajesz obracać silnikiem, zmieniasz
    kierunek obrotów lub co Ci przyjdzie do głowy.
  • Helpful post
    #5
    mirekk36
    Level 42  
    Możesz zamiast podporogramów zrobić po ludzku funkcje i przekazywać do nich liczba_krokow jako parametr z opcją by val czyli przez wartość a nie broń boże przez referencję czyli by ref

    Dodano po 4 [minuty]:

    janbernat wrote:

    No i co z tego że rozumiem sprzęt- jak programista ze mnie jak z koziej ...trąba.


    Ty nie opowiadaj tu takich banialuk nie z tej ziemii ;) bo całkiem nieźle sobie radzisz, wystarczy spojrzeć jak korzystasz z Timerów itp ..... więc wcale nie jest tak źle. A przecież wszystkiego się od ręki w 5 sek nie zrobi ... tak że troszkę cierpliwości i wszystko się uda ;)
  • #6
    janbernat
    Level 38  
    No właśnie podejrzewałem że to jakaś moja głupota.
    Ale jak zrobię funkcję (albo procedurę) z parametrem byval- to zmiana parametru w procedurze (funkcji) nie będzie widoczna na zewnątrz,gdyż dotyczy tylko jej kopii.
    A mi (chyba) zależy aby zmiana liczba_krokow była widoczna na zewnątrz- po przejściu do innej funkcji.
    Uczenie się naraz C i Bascoma w podeszłym wieku prowadzi do totalnego zgłupienia.
    Dzięki- jutro wieczorem będę zmieniał i kombinował.
    A jutro w pracy będę dopieszczał sterowanie plotera frezującego silnikami krokowymi.
    Już ładnie zaczął chodzić-1.5x1.5m.
  • Helpful post
    #7
    Pittt
    Level 32  
    Silnik kręci, chyba dla tego że nigdzie nie liczysz ile nakręciłeś, a pętla jest wywoływana w kółko o ile zmienna kierunek jest np równa 3, nawet z ilością kroków 0 raz się wykona i a to wystarczy do zmiany kroku (case) które i tak są zależne od przerwania timera. Na początek, w warunku IF od razu po wywołaniu Kier_lewo, zmienną Kier ustaw na 0.
  • #8
    janbernat
    Level 38  
    No, dzięki światłym uwagom hose2 coś udało się zrobić.
    Aktualny kod:
    Code:

    'Program do sterowania małych silników krokowych za pomocą ATMega8 i układu L6219 lub LB1845
    'sterowanie ćwierćrokowe, zasilanie 30V


    $regfile "m168def.dat"
    $crystal = 4915200

    '********* Konfiguracja wyświetlacza *********
    $lib "Lcd4busy.lib"
    Const _lcdport = Portd
    Const _lcdddr = Ddrd
    Const _lcdin = Pind
    Const _lcd_e = 1
    Const _lcd_rw = 2
    Const _lcd_rs = 3
    Config Lcd = 20 * 4

    '*********** Konfiguracja wyjść do sterowania L6219 ************
    Config Portc = Output
    Ph1 Alias Portc.0             'kierunek przepływu prądu w uzwojeniu Ph1
    Ph2 Alias Portc.1             'kierunek przepływu prądu w uzwojeniu Ph2
    I01 Alias Portc.2             'napięcie dostarczane do uzwojeń- 1 , 2/3 lub 1/3 Imax
    I11 Alias Portc.3
    I02 Alias Portc.4
    I12 Alias Portc.5
    Reset Ph1                     ' na początek ustawiamy krok 0
    Reset I01
    Reset I11
    Set I02
    Set I12
    Reset Ph2

    '****** Ustawianie zmiennych do kontroli pracy silnika ***************
    Dim Kier As Byte
    Kier = 0
    Dim Liczba_krokow As Word
    Liczba_krokow = 10000
    Dim Stan As Word
    Stan = 0
    Dim Kroki As Word
    Kroki = 0

    '********** PortB jako wejście z podciąganiem ***************
    Config Portb = Input
    Set Portb

    '********** ustawienie przerwań ****************
    sei

    Config Timer0 = Timer , Prescale = 8       ' teraz da ok. 0.417us- ale może skrócić
    'Config Timer2 = Timer , Prescale = 1024
    Enable Ovf0
    On Ovf0 Step_delay
    '*********** Ustawianie parametrów programu ********

    Dim Temp0 As Byte
    Dim Opoznienie_odczytu As Byte


    Dim Liczba_powtorzen As Byte
    Dim Kat As Single
    Dim Liczniczek As Byte
    Liczniczek = 100
    Dim U1 As Byte
    U1 = 4
    Dim Up As Byte
    Dim Ul As Byte
    Dim Us As Byte
    Up = 255
    Ul = 255
    Ul = 255
    Dim Rampa As Word
    Rampa = 65000

    Dim Koniec As Word
    Koniec = 1000



    Dim Next_step As Byte
    Next_step = 0
    Dim Flaga As Byte
    Flaga = 0



    Cls
    Cursor Off
    Locate 1 , 1
    Lcd "ustal kierunek "



    Do

       If Flaga = 1 Then          'gdy jest przerwanie od Timer0- co 237us
         If Pinb.0 = 0 Then       'i jest wciśnięty przycisk PIND.2- ustawianie kierunku jednym przyciskiem
             Incr Opoznienie_odczytu       'no bo przycisk ma drgania dłużej niż 237us- niech zwiększy
                                            'to sprawdzanie powtórne do 17ms

             If Opoznienie_odczytu >= 70 Then       'dajmy mu na wygaszenie drgań 17ms

                If Temp0 = 0 Then ' i jest zezwolenie na zmianę stanu
                   Gosub Ustawianie
                   Temp0 = 1      ' zablokuj zezwolenie na zmianę stanu
                End If

                Opoznienie_odczytu = 0       'Jak już ustawił kierunek to pozwolimy mu liczyć od początku-
                                              'po powtórnym naciśnięciu PIND.2
              End If

          Else
             Temp0 = 0            'zezwalaj na zmiany
             Opoznienie_odczytu = 0
          End If

          If Kier = 1 Then
             For Kroki = Stan To Liczba_krokow
             Gosub Kier_prawo
             'Fourthline
             'Cls
             'Lcd Stan
             Next

          End If

          If Kier = 2 Or Kier = 0 Then
             Gosub Kier_stop
          End If

          If Kier = 3 Then
             For Kroki = Stan To Liczba_krokow
             Gosub Kier_lewo
             'Fourthline
             'cls
             'Lcd Stan
             Next

          End If

          Flaga = 0


       End If
          Debounce Pinb.3 , 0 , Ustaw_liczba_krokow

    Loop
    End


    Step_delay:                   'ten timer określa szybkość z jaką szybkością kręci się silnik- teraz ok0.25ms/ impuls
       Timer0 = 60                'no to skracamy- ten silnik się jeszcze kręci- ale na jakimś innym moze to trzeba zmienić
                         'tu jest ok.319us obliczone a xus zmierzone- procesor jednak coś wolno liczy
       Flaga = 1


          Incr Next_step          'sterowanie 1/4 kroku- 16 stanów
             If Next_step >= 16 Then
                Next_step = 0
          End If


    Return


    Ustawianie:

          Select Case Kier
             Case 0
               Locate 1 , 1
               Lcd "kierunek- lewo " ; Kier
             Case 1
               Locate 1 , 1
               Lcd "kierunek- stop " ; Kier
             Case 2
               Locate 1 , 1
               Lcd "kierunek- praw " ; Kier
             Case 3
               Locate 1 , 1
               Lcd "kierunek- stop " ; Kier

           End Select

        Incr Kier
         If Kier >= 4 Then
           Kier = 0
         End If


    Return

    Kier_prawo:                   'Sterowanie układu L6219 lub LB1845- w przypadku sterowania STEP, DIR ten fragment należy uprościć

        Select Case Next_step

             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
                Incr Stan
             Case 1
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
                Incr Stan
             Case 2
                Reset Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
                Incr Stan
             Case 3
                Reset Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
                Incr Stan
             Case 4
                Set Ph1 : Set I11 : Set I01 : Reset Ph2 : Reset I12 : Reset I02
                Incr Stan
             Case 5
                Set Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
                Incr Stan
             Case 6
                Set Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
                Incr Stan
             Case 7
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
                Incr Stan
             Case 8
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
                Incr Stan
             Case 9
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
                Incr Stan
             Case 10
                Set Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
                Incr Stan
             Case 11
                Set Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
                Incr Stan
             Case 12
                Reset Ph1 : Set I11 : Set I01 : Set Ph2 : Reset I12 : Reset I02
                Incr Stan
             Case 13
                Reset Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
                Incr Stan
             Case 14
                Reset Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
                Incr Stan
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
                Incr Stan

          End Select

    Return

    Kier_lewo:

          Select Case Next_step

             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
                Decr Stan
             Case 1
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
                Decr Stan
             Case 2
                Reset Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
                Decr Stan
             Case 3
                Reset Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
                Decr Stan
             Case 4
                Set Ph1 : Set I11 : Set I01 : Set Ph2 : Reset I12 : Reset I02
                Decr Stan
             Case 5
                Set Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
                Decr Stan
             Case 6
                Set Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
                Decr Stan
             Case 7
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
                Decr Stan
             Case 8
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
                Decr Stan
             Case 9
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
                Decr Stan
             Case 10
                Set Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
                Decr Stan
             Case 11
                Set Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
                Decr Stan
             Case 12
                Reset Ph1 : Set I11 : Set I01 : Reset Ph2 : Reset I12 : Reset I02
                Decr Stan
             Case 13
                Reset Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
                Decr Stan
             Case 14
                Reset Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
                Decr Stan
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
                Decr Stan

          End Select

    Return

    Kier_stop:                    'stop ma zachować aktualne położenie wirnika
    Stan = Pinc                   'No tu coś jest nie tak-

    Return

    Ustaw_liczba_krokow:          'Tu jest ustawianie- czas bez znaczenia i wszystkie paskudy typu wait czy debouce dozwolone

    Cls
    Lcd "liczba krokow"
    Liczba_krokow = 1
    Do

    Waitus 500
    Decr U1
      If Pinb.1 = 1 Then
       Liczniczek = 100
      End If

       If Pinb.1 = 0 Then
        If U1 = 0 Then
          U1 = Liczniczek
          Decr Liczniczek
          If Liczniczek < 2 Then Liczniczek = 2
              If Liczba_krokow <= 16000 Then
                 Kat = Liczba_krokow * 0.029296875
              End If

              If Liczba_krokow >= 16000 Then
                Liczba_krokow = 16000
              End If
                Incr Liczba_krokow

                Lowerline
                Lcd " ->  " ; Liczba_krokow ; "      "
                Thirdline
                Lcd "Kat " ; Kat ; "        "

          End If
       End If


       If Pinb.2 = 1 Then
        Liczniczek = 100
       End If

        If Pinb.2 = 0 Then
         If U1 = 0 Then
           U1 = Liczniczek

            Decr Liczniczek
          If Liczniczek < 2 Then Liczniczek = 2
            If Liczba_krokow <= 16000 Then
              Kat = Liczba_krokow * 0.029296875
            End If

            If Liczba_krokow <= 1 Then
              Liczba_krokow = 1
            End If
              Decr Liczba_krokow

              Lowerline
              Lcd " <-  " ; Liczba_krokow ; "      "
              Thirdline
              Lcd "Kat " ; Kat ; "        "

         End If
        End If




        If Pinb.4 = 0 Then Exit Do
    Loop
    Return

    Teraz się kręci o zadaną liczbę kroków.
    Oczywiście pojawiły się nowe problemy.
    Po wybraniu kierunku silnik się kręci prawo-lewo o zadaną liczbę kroków.
    Ale nie wraca do pozycji początkowej.
    No bo w kier_stop daję stan=PINC.
    To bez sensu- ale jak wyremuję to nie mogę zmienić kierunku obrotów.
    I nie wiem co tam dać.
    No ale jeden błąd poprawiłem- inne błedy oczywiście wyszły.
    Chciałbym w pełni kontrolować ilość kroków jakie silnik robi- z dokładnością do 1/4 kroku- czyli jak jest sterowany.
    Może to jest przerost wymagań.
    Kręci się, jest sterowany programowo/sprzętowo z tego samego procesora.
    Ale to jeszcze nie to.
    No a potem rampa.

    No moze mi się uda- z Waszą pomocą.
  • Helpful post
    #9
    Pittt
    Level 32  
    Code:
         If Kier = 1 Then
    
             While Kroki <> Liczba_krokow     'do puki zmienne sa rozne
                  Gosub Kier_prawo
             End
          End If

          If Kier = 2 Or Kier = 0 Then
               Gosub Kier_stop
          End If

          If Kier = 3 Then
             While Kroki <> 0                       'do puki zmienne sa rozne
                  Gosub Kier_lewo
             End
          End If

      .
      .

    Kier_prawo:                   'Sterowanie układu L6219 lub LB1845- w przypadku sterowania STEP, DIR ten fragment należy uprościć

        Select Case Next_step

             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
                Incr Stan
             .
             .
             .
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
                Incr Stan
               
     
               If Next_step <> Next_step_old Then  'Sprawdzam czy timer zmienil krok
                    Kroki = Kroki + 1
               END If
               Next_step_old = Next_step     ' zapamietuje poprzedni krok

          End Select

    Return

    Kier_lewo:

          Select Case Next_step

             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
                Decr Stan
               .
               .
               .
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
                Decr Stan
               
               If Next_step <> Next_step_old Then  'Sprawdzam czy timer zmienil krok
                    Kroki = Kroki - 1
               END If
               Next_step_old = Next_step     ' zapamietuje poprzedni krok

          End Select





          End Select


    Jeśli chodzi o powrót do tego samego miejsca Spróbuj tak, nie mam pewności co do składni While i znaku różne.

    Teraz lepiej, ale może się jakiś kroczek gubić przy zmianie obrotów.

    Ale chyba nie powinien.
  • #10
    janbernat
    Level 38  
    Zapoznałem się dokładniej z poleceniem rotate.
    I to jest rozwiązanie.
    Ten program należy przerobić- na razie poszedł w odstawkę.
  • #11
    janbernat
    Level 38  
    Przepraszam za post pod postem- ale w końcu zrobiłem.
    Code:

    'Program do sterowania małych silników krokowych za pomocą ATMega168 it.p. i układu L6219 lub LB1845
    'sterowanie ćwierćrokowe, zasilanie 40V

    $regfile "m168def.dat"
    $crystal = 8000000
    Config Lcd = 16 * 2
    $lib "Lcd4busy.lib"
    Const _lcdport = Portd
    Const _lcdddr = Ddrd
    Const _lcdin = Pind
    Const _lcd_e = 1
    Const _lcd_rw = 2
    Const _lcd_rs = 3
    Ddrb = &HFF
    sei

    Config Timer0 = Timer , Prescale = 64             ' teraz da na 1/4 kroku ok. 2.048ms- ale można skrócić
    Enable Ovf0
    On Ovf0 Step_delay
    Config Pinc.0 = Input
    Set Portc.0
    Kier_lewo Alias Pinc.0                            'jak wciśniemy ten przycisk to się kręci w lewo
    Config Pinc.1 = Input
    Set Portc.1
    Kier_prawo Alias Pinc.1                           'a jak ten- to w prawo
    Ph1 Alias Portb.0                                 'kierunek przepływu prądu w uzwojeniu Ph1
    Ph2 Alias Portb.1                                 'kierunek przepływu prądu w uzwojeniu Ph2
    I01 Alias Portb.2                                 'napięcie dostarczane do uzwojeń- 1 , 2/3 lub 1/3 Imax
    I11 Alias Portb.3
    I02 Alias Portb.4
    I12 Alias Portb.5

    Set I01                                           ' na początek ustawiamy mały prąd
    Set I11
    Set I02
    Set I12

    Dim Next_step As Word                             'next_step będzie miał 16 stanów- sterowanie 1/4 kroku
    Next_step = 1                                     'stan początkowy 1- żeby miało się co kręcić w rotate

    Cls
    Cursor Off
    Locate 1 , 1
    Lcd "Eppur si muove"

    Do
    '
    '
    '
    '
    Loop
    End


    Step_delay:

    Timer0 = 200                                      'no to skracamy- teraz jest co 0.448ms- ten silnik się jeszcze kręci- ale na jakimś innym moze to trzeba zmienić

    If Kier_lewo = 0 And Kier_prawo = 1 Then
       Rotate Next_step , Left
       Gosub Kroki

    End If

    If Kier_prawo = 0 And Kier_lewo = 1 Then
       Rotate Next_step , Right
       Gosub Kroki

    End If

    Return


    Kroki:

        Select Case Next_step

             Case 1
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
             Case 2
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 4
                Reset Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 8
                Reset Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 16
                Set Ph1 : Set I11 : Set I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 32
                Set Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 64
                Set Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 128
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 256
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
             Case 512
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
             Case 1024
                Set Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 2048
                Set Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 4096
                Reset Ph1 : Set I11 : Set I01 : Set Ph2 : Reset I12 : Reset I02
             Case 8192
                Reset Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 16384
                Reset Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 32768
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02


          End Select

    Return

    Teraz muszę zrobić to w C.
  • Helpful post
    #12
    Dr.Vee
    VIP Meritorious for electroda.pl
    Masz jeden błąd - Next_step nigdy nie przyjmie wartości 0, co najwyżej 1.

    Jeśli chodzi o C, to sugerowałbym użycie tablicy:
    Code:

    enum { NUM_STEPS = 16 };
    enum { STEP_MASK = 0x3f };
    /*
     * Układ portu B:  x  x  I12  I02  I11  I01  Ph2  Ph1
     */
    static const uint8_t steps[NUM_STEPS] =
    {
        /* dla avr-gcc można użyć literałów binarnych: 0x30 = 0b00110000 */
        0x30,
        0x20,
        /* 14 kolejnych wartosci ... */
    };

    /* obrót o 1/4 kroku w prawo: advance_step(1) */
    /* obrót o 1/4 kroku w lewo:  advance_step(-1) */
    void advance_step(int8_t nsteps)
    {
        static uint8_t stepNum = 0;

        PORTB = (PORTB & ~STEP_MASK) | steps[stepNum];
        stepNum += nsteps;
        stepNum %= NUM_STEPS;
    }


    Pozdrawiam,
    Dr.Vee
  • #13
    janbernat
    Level 38  
    Dzięki- już poprawiłem.
    Zauważenie braku 1/4 kroku na pracującym silniku jest raczej niemożliwe.
    Zrobiłem- a raczej przerobiłem z podręcznika taką funkcję:
    Code:

    uint16_t rotate(uint16_t liczba, int16_t il_bitow)
       {
          uint16_t wynik, bits;
          if(il_bitow>0)
             il_bitow=il_bitow%16;         
          else
             il_bitow=-(-il_bitow%16);
          if (il_bitow==0)
             wynik=liczba;
          else if(il_bitow>0)
          {
          bits=wynik>>(16-il_bitow);
          wynik=liczba<<il_bitow | bits;
          }
          else
          {
          il_bitow=-il_bitow;
          bits=liczba<<(16-il_bitow);
          wynik=liczba>>il_bitow|bits;
          }               
          return wynik;
       }

    Ale jeszcze tego nie sprawdzałem.
    W C jestem jeszcze na etapie przepisywania z usiłowaniem zrozumienia.
    Wyciągam więc podręcznik i wpatruję się w to co napisałeś.
  • #14
    carkar
    Level 15  
    Lepiej to napisać w ASMIE i pisać dzień, niż napisać w C w 1h a potem tydzień poprawiać....

    Liczba wyświetleń zaraz dobije liczby szatańskiej... :)
  • #15
    janbernat
    Level 38  
    Chyba wykrakałeś tę liczbę szatańską- przy 40V zasilania z płytki zaczął się wydobywać dym.
    Uporządkowany trochę kod- jeszcze w bascomie- ale łatwiej będzie wystawiać stan portu w C.
    Code:

    'Program do sterowania małych silników krokowych za pomocą ATMega168 it.p. i układu L6219 lub LB1845
    'sterowanie ćwierćrokowe, zasilanie 40V

    $regfile "m168def.dat"
    $crystal = 8000000
    Config Lcd = 16 * 2
    $lib "Lcd4busy.lib"
    Const _lcdport = Portd
    Const _lcdddr = Ddrd
    Const _lcdin = Pind
    Const _lcd_e = 1
    Const _lcd_rw = 2
    Const _lcd_rs = 3
    Ddrb = &HFF
    sei

    Config Timer0 = Timer , Prescale = 64             ' teraz da na 1/4 kroku ok. 2.048ms- ale można skrócić
    Enable Ovf0
    On Ovf0 Step_delay
    Config Pinc.0 = Input
    Set Portc.0
    Kier_lewo Alias Pinc.0                            'jak wciśniemy ten przycisk to się kręci w lewo
    Config Pinc.1 = Input
    Set Portc.1
    Kier_prawo Alias Pinc.1                           'a jak ten- to w prawo
    Ph1 Alias Portb.0                                 'kierunek przepływu prądu w uzwojeniu Ph1
    Ph2 Alias Portb.1                                 'kierunek przepływu prądu w uzwojeniu Ph2
    I01 Alias Portb.2                                 'napięcie dostarczane do uzwojeń- 1 , 2/3 lub 1/3 Imax
    I11 Alias Portb.3
    I02 Alias Portb.4
    I12 Alias Portb.5

    Set I01                                           ' na początek ustawiamy mały prąd
    Set I11
    Set I02
    Set I12

    Dim Next_step As Word                             'next_step będzie miał 16 stanów- sterowanie 1/4 kroku
    Next_step = 1                                     'stan początkowy 1- żeby miało się co kręcić w rotate

    Cls
    Cursor Off
    Locate 1 , 1
    Lcd "Eppur si muove"

    Do
    '
    '
    '
    '
    Loop
    End


    Step_delay:

    Timer0 = 200                                      'no to skracamy- teraz jest co 0.448ms- ten silnik się jeszcze kręci- ale na jakimś innym moze to trzeba zmienić

    If Kier_lewo = 0 And Kier_prawo = 1 Then
       Rotate Next_step , Left
       Gosub Kroki

    End If

    If Kier_prawo = 0 And Kier_lewo = 1 Then
       Rotate Next_step , Right
       Gosub Kroki

    End If

    Return


    Kroki:

        Select Case Next_step

             Case 1
                   'Set I12 : Set I02 : Reset I11 : Reset I01 : Reset Ph2 : Reset Ph1
                'Portb = &B00110000
                Portb = &H30
             Case 2
                    'Set I12 : Reset I02 : Reset I11 : Reset I01 : Reset Ph2 : Reset Ph1
                'Portb = &B00100000
                Portb = &H20
             Case 4
                   'Reset I12 : Set I02 : Reset I11 : Set I01 : Reset Ph2 : Reset Ph1
                'Portb = &B00010100
                Portb = &H14
             Case 8
                    'Reset I12 : Reset I02 : Set I11 : Reset I01 : Reset Ph2 : Reset Ph1
                'Portb = &B00001000
                Portb = &H8
             Case 16
                  'Reset I12 : Reset I02 : Set I11 : Set I01 : Reset Ph2 : Set Ph1
                'Portb = &B00001101
                Portb = &HD
             Case 32
                  'Reset I12 : Reset I02 : Set I11 : Reset I01 : Reset Ph2 : Set Ph1
                'Portb = &B00001001
                Portb = &H9
             Case 64
                ' Reset I12 : Set I02 : Reset I11 : Set I01 : Reset Ph2 : Set Ph1
                'Portb = &B00010101
                Portb = &H15
             Case 128
                  'Set I12 : Reset I02 : Reset I11 : Reset I01 : Reset Ph2 : Set Ph1
                'Portb = &B00100001
                Portb = &H21
             Case 256
                   ' Set I12 : Set I02 : Reset I11 : Reset I01 : Set Ph2 : Set Ph1
                'Portb = &B00110011
                Portb = &H33
             Case 512
                  ' Set I12 : Reset I02 : Reset I11 : Reset I01 : Set Ph2 : Set Ph1
                'Portb = &B00100011
                Portb = &H23
             Case 1024
                 '  Reset I12 : Set I02 : Reset I11 : Set I01 : Set Ph2 : Set Ph1
                'Portb = &B00010111
                Portb = &H17
             Case 2048
                '    Reset I12 : Reset I02 : Set I11 : Reset I01 : Set Ph2 : Set Ph1
                'Portb = &B00001011
                Portb = &HB
             Case 4096
                '    Reset I12 : Reset I02 : Set I11 : Set I01 : Set Ph2 : Reset Ph1
                'Portb = &B00001110
                Portb = &HE
             Case 8192
                '   Reset I12 : Reset I02 : Set I11 : Reset I01 : Set Ph2 : Reset Ph1 :
                'Portb = &B00001010
                Portb = &HA
             Case 16384
                 '  Reset I12 : Set I02 : Reset I11 : Set I01 : Set Ph2 : Reset Ph1
                'Portb = &B00010110
                Portb = &H16
             Case 32768
                '    Set I12 : Reset I02 : Reset I11 : Reset I01 : Set Ph2 : Reset Ph1
                'Portb = &B00100010
                Portb = &H22
          End Select

    Return
    '(

    Ph1 Alias Portb.0                                 'kierunek przepływu prądu w uzwojeniu Ph1
    Ph2 Alias Portb.1                                 'kierunek przepływu prądu w uzwojeniu Ph2
    I01 Alias Portb.2                                 'napięcie dostarczane do uzwojeń- 1 , 2/3 lub 1/3 Imax
    I11 Alias Portb.3
    I02 Alias Portb.4
    I12 Alias Portb.5
    ')

    P.S.
    Sytuacja opanowana- radiator się odkleił- jest na silikon przyklejony.
    P.S.2
    Silnik ma 43x43mm.
    I co zauważyłem- przy 35V zasilania prąd (średni) pobierany z zasilacza wynosi tylko 150mA.
    A układ może dać 0.5A- a w szczycie 0.75A.
    Jak się przestanę w tym temacie odzywać- to będzie znaczyć że zmieniłem oporniki pomiaru prądu na mniejsze i wszystko poszło z dymem.
    Ale na razie- silnik nareszcie chodzi jak ja chcę- a nie jak on chce.
  • Helpful post
    #16
    Dr.Vee
    VIP Meritorious for electroda.pl
    Zapomnij o rotacji bitów, nie jest tutaj do niczego potrzebna.
    Zamiast używać potęg dwójki 2^0..2^15 możesz po prostu użyć liczb 0..15.
    Liczby używasz w switch .. case, albo używasz tablicy z jednym elementem na krok i odpowiednio indeksujesz (jak w przykładzie).

    Pozdrawiam,
    Dr.Vee
  • #17
    janbernat
    Level 38  
    Okropnie "gęsty" ten kod.
    Rozumiem już (chyba) static uint8_t stepNum = 0;
    Ale nie rozumiem jeszcze ostatniej linijki:
    stepNum %= NUM_STEPS;
    Po co jest to dzielenie modulo?
  • Helpful post
    #18
    Dr.Vee
    VIP Meritorious for electroda.pl
    Modulo jest po to, żebyś nie wyszedł poza zakres tablicy, no i żeby zrealizować przejścia:
    Code:

    15 -> 0: 15 + 1 == 16, 16 % 16 == 0.
    0 -> 15:  0 - 1 == -1 == 255, 255 % 16 = 15.

    O wydajność się nie martw, już pierwszy kompilator C optymalizował operacje dzielenia i modulo 2^n.

    Zmienna statyczna w funkcji jest inicjowana tylko za pierwszym razem. Później zachowuje swoją wartość pomiędzy wywołaniami funkcji - coś jak ukryta zmienna globalna :)

    Pozdrawiam,
    Dr.Vee
  • #19
    janbernat
    Level 38  
    Dzięki.
    Static- inicjowana tylko za pierwszym razem- tak jak wyczytałem w podręczniku.
    O wydajność się nie martwię- przeczytałem (ze słabym zrozumieniem) książkę "Wysokie C".
    Ze skomplikowaną składnią kompilator sobie poradzi- ale ja pewnie nie.
    Ale dzielenia modulo aby nie wyjść poza zakres- to tego nigdzie nie znalazłem.
    Dlatego próbowałem z rotate.
    Jeszcze raz- dziękuję.
  • #20
    janbernat
    Level 38  
    Znowu post pod postem- ale po długim grzebaniu w książkach i w sieci- a zwłaszcza dzięki pomocy Dr_Vee działa w C.
    Code:

    #include <avr/interrupt.h>
    #include "HD44780.h"
    #include <stdint.h>

    int main(void)
    {
    // ustawianie rejestrów
       sei();
       DDRC=0;
       PORTC=255;
       DDRB=255;
       TCCR0A=0;
       TCCR0B|=(_BV(CS00)|_BV(CS01));
       TIMSK0|=_BV(TOIE0);

       char *text="E pur si muove";
       LCD_Initalize();
       LCD_WriteText(text);
       _delay_ms(500);

       while(1)
       {

    //   LCD_WriteText(text);
    //   LCD_GoTo(40,2);
    //   LCD_WriteText(text);

       }

    }
    //*************************************  Program Dr_Vee

    enum { NUM_STEPS = 16 };
    enum { STEP_MASK = 0x3f };
    /*
     * Układ portu B:  x  x  I12  I02  I11  I01  Ph2  Ph1
     */
    static const uint8_t steps[NUM_STEPS] =
    {
        /* dla avr-gcc można użyć literałów binarnych: 0x30 = 0b00110000 */
        0x30, 0x20, 0x14, 0x8, 0xd, 0x9, 0x15, 0x21, 0x33, 0x23, 0x17, 0xb, 0xe, 0xa, 0x16, 0x22
    };

    /* obrót o 1/4 kroku w prawo: advance_step(1) */
    /* obrót o 1/4 kroku w lewo:  advance_step(-1) */
    void advance_step(int8_t nsteps)
    {
        static uint8_t stepNum = 0;

        PORTB = (PORTB & ~STEP_MASK) | steps[stepNum];
        stepNum += nsteps;
        stepNum %= NUM_STEPS;
    }
    //********************************************* A to już moje //wypociny
    ISR(TIMER0_OVF_vect)
       {

       TCNT0=200;
       if(bit_is_clear(PINC,PC0))
       advance_step(1);
       if(bit_is_clear(PINC,PC1))
       advance_step(-1);

       }

    To w zasadzie początek.
    Teraz trzeba obsłużyć klawisze w przerwaniu i sprawić żeby silnik kręcił się o określoną ilość kroków.
    A to jest wersja obsługująca określoną ilość kroków- może się komuś przyda:
    Code:

    //********************************************* A to już moje wypociny
    //**silnik ma nietypowy skok- 1.875 deg/step co daje 768 ipulsów/ na obrót przy sterowaniu 1/4 kroku
    //**dla innego silnika należy zmienić wartości dodawane do x i z
    //**ta wersja pozwala na uzyskanie pełnego obrotu silnika w lewo i prawo
    //**albo dowolnej ilości kroków.
    //**tę wersję napisał mój najmłodszy- i działa chyba dobrze- bo silnik wraca do pczątkowego położenia
    ISR(TIMER0_OVF_vect)
       {
       static uint16_t x;
       TCNT0=200;
       if(x!=0)
       {
       advance_step(1);
       x=x-1;
       }
       else
       {
       if(bit_is_clear(PINC,PC0))
          {
          advance_step(1);
          x=x+767;
          }
       }
       static uint16_t z;
       if(z!=0)
       {
       advance_step(-1);
       z=z-1;
       }
       else
       {
       if(bit_is_clear(PINC,PC1))
          {
          advance_step(-1);
          z=z+767;
          }
       }
       }


    Albo tak:
    Code:

    ISR(TIMER0_OVF_vect)
       {TCNT0=200;

    uint16_t ilosc_krokow_na_obrot=768;
    static int16_t przes=0;
    static uint16_t krok=1;
    static int16_t obr=0;
    static uint8_t blokada;

    if(przes==0)
       {
       if(blokada==0)
          {   
             if(bit_is_clear(PINC,PC0))
                {
                   przes+=768;
                   blokada=10;
                }
             if(bit_is_clear(PINC,PC1))
                {
                   przes-=384;
                   blokada=10;
                }
          }
       else
          {
          if(bit_is_set(PINC,PC1)&&bit_is_set(PINC,PC0))
             {
             blokada--;

             }
          }
       }
    if(przes!=0)
       {
       
       //Funkcja przesuwania
             if(przes>0)
                {
                advance_step(-1);
                przes-=1;
                krok-=1;
                }
             else
                {
                if(przes<0)
                   {
                   advance_step(1);
                   przes+=1;
                   krok+=1;
                   }
                }
       //koniec funkcji przesuwania
       
    }
       //funkcja liczenia pozycji
       if(krok<1)
          {
             krok=ilosc_krokow_na_obrot;
             obr-=1;
          

          }
       else
          {
          if(krok>ilosc_krokow_na_obrot)
             {
             krok=1;      
             obr+=1;
               
             }
          }
                            
       //koniec funkcji liczenia pozycji

       //aktualna pozycja w krokach to (ilosc_krokow_na_obrot*obr)+krok

    Proszę o komentarze- jeśli ktoś tu zagląda.
    Może to zrobić lepiej.