Elektroda.pl
Elektroda.pl
X
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 3422 19
  • #1
    janbernat
    Level 38  
    
    '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 17  
    Witam
    janbernat wrote:
    
    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
    
    
    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:
    
    '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  
         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.
    
    '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:
    
    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ę:
    
    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.
    
    '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:
    
    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.
    
    #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:
    
    //********************************************* 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:
    
    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.