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

[ATTiny2313][Bascom]-sterownik silnika krokowego początkujac

21 Lut 2011 17:06 3640 6
  • Poziom 15  
    Zbudowałem sterownik silnika krokowego na parze L297 i L298.Steruje sie to standardowo sygnałem DIR-kierunek, ENABLE-załączenie silnika,H/L -praca krok półkrok, CLK -impulsy zegarowe sterujące szybkością pracy krokowca. Sterownik działa , wypróbowany na generatorku NE555 jest OK. Przyszedł czas na sterowanie tego z procka.Sama baza zbudowana jest z 5 przycisków , wyświetlacz LCD i oczywiście procka AtTiny2313.Dwa klawisze sterują szybciej / wolniej, jeden start, jeden stop i jeden mam na razie nie skonfigurowany. Z obsługą klawiatury sobie radzę tylko mam problem z generowaniem sygnału CLK.
    To znaczy ja go generuje na zasadzie zmiany czasu trwania stanu wysokiego oraz niskiego na konkretnym pinie komendą WAITMS oraz TOGGLE. Przykładowo wkleję kawałek kodu dotyczący właśnie tej procedury zmiany częstotliwości tych impulsów
    Code:

    A=30

     If Pinb.0 = 0 Then A = A + 1         'Zmiana CLK podczas pracy + 1ms po naciśnieciu przycisku 1

     If Pinb.1 = 0 Then A = A - 1          'Zmiana CLK podczas pracy - 1ms po naciśnieciu przycisku 2

     If Pinb.2 = 0 Then A = 40              'Szybkie ustawienie CLK na 40ms podczas pracy po naciśnieciu przycisku 3

     If Pinb.4 = 0 Then Tryb = 0            'Stop CLK  silnik w hamulcu magnetycznym po nacisnieciu przycisku 5

               'Zmiana czasow

     Waitms A
       Portd.6 = 1
       Waitms A
       Toggle Portd.6


      Locate 1 , 4                        'Ustaw kursor w 1 wierszu i 1 kolumnie wyświetlacza
       Lcd A


       Locate 2 , 1                       'Ustaw kursor w 1 wierszu i 1 kolumnie wyświetlacza

       Lcd "  milisekund   "


    Jak inaczej podejść do tematu generowania przebiegu kwadratowego na konkretnym pinie aby można potem nad nim zapanować. O co mi chodzi, mianowicie obecnie ustawiam tą częstotliwość , niby silnik kręci działa, widzę te ms na wyświetlaczu jest OK. Ale gdybym chciał aby silnik powiedzmy przesunął coś w konkretnym czasie albo na konkretną odległość(urządzenie ma przesuwać wózek z aparatem foto tzw slider fotograficzny), potem np. postał minutę i znowu wykonał podobny interwał czasowy, to z tego mojego kodu raczej nic nie wyduszę. Jak mi sie wydaje , trzeba będzie zaprzęgnąć TIMERY do kontroli a może nawet jakieś przerwania ale w tym to jestem na obecny czas zielony z lekka.Może na początek , jak wygenerować przebieg kwadratu nie używając procedury WAITMS i Toggle. Wiem o nie stabilności procedury WAITMS i to że moje np 40ms wcale nie jest akurat dokładnie 40milisekundami.Na zakończenie napiszę, że mój obecny programik jest bardziej rozbudowany o deklaracje zmiennych i resztę konfiguracji LCD i klawiszy.Obecnie po włączeniu ustawiam wstępny czas i naciskam start, silnik rusza i mogę nadal go korygować wolniej szybciej oraz go zatrzymać na hamulcu magnetycznym.Chodzi mi głównie o przebieg CLK i kontrolę nad tym przebiegiem.Gdy kod będzie zbyt obszerny dla 2313 zawsze mogę przeskoczyć na Atmega 8.
  • Poziom 14  
    musisz timer ustawić w CTC Mode (TCCR0A)
    czestotliwość ustawiasz wpisując odpowiednią wartość w OCR0A
    (DS strona 72)
  • Poziom 34  
    Musi kolega jeszcze dobrać się do przycisków bo teraz każde przejście programu będzie wykonywało operację na liczbie A , więc proponuje wprowadzić opóźnienie mające zapobiegać drganiu styków a następnie czekać na zwolnienie przycisku przed zmianą wartości A . Dodatkowo można wzbogacić urządzenie o mechanizm automatycznego zwiększania wartości A w przypadku długiego naciśnięcia przycisku .
  • Poziom 15  
    Ok posiedziałem ciut, poczytałem w necie jak się używa te Timery i ich przepełnienia . Powstał taki oto kod .Proszę wyświetlacz traktować jako pomoc pokazującą mi ile już wystąpiło przepełnień, zresztą bardzo fajnie to pokazuje.
    Ramowa zasada jest taka - programik ma zliczać przepełnienia do 2108 i się zatrzymać po osiągnięciu tej sumy(wstępnie ta wartość jest wzięta z sufitu, potem policzę ile impulsów to będzie koniec łoża wózka). Jednak w trakcie pracy , co X przepełnień programik się zatrzymuje na T sekund (obecnie programowo ustalone 10przepełnień i 1s).I tu mam problem o który teraz chcę zapytać jak go rozwiązać- w którym miejscu programu wstawić procedury warunkowe sprawdzające na starcie programu klawisze zadeklarowane jako te które mają wprowadzać dane X oraz T. Może zagmatwanie piszę ale starałem się to opisać komentarzami w programie, co chciałbym zrobić .
    W pętli DO... Loop sie raczej nie da, program szaleje, więc jak to zrobić.
    Oto programik:
    Code:

      $regfile = "attiny2313.dat"                              'rejestry mikrokontrolera atmega8

    Config Lcd = 16 * 2

    Config Lcdpin = Pin , Db4 = Portd.3 , Db5 = Portd.2 , Db6 = Portd.1 , Db7 = Portd.0 , E = Portd.4 , Rs = Portd.6       'ustawienie Wyswietlacza
    Cursor Off
    Cls

      Dim L As Integer                                          'zmienna ilosci przepelnien Timera1
      Dim X As Integer                                          'zmienna okreslajaca czas pracy silnika
      Dim Y As Integer                                          'druga zmienna dodawana do czasu pracy
      Dim T As Integer                                          'zmienna określajaca czas wstrzymania  Timera1


     Config Portb.3 = Output                                    'linia pb3 jako wyjście

    '********************************************************************************************************
    ' te porty właśnię chcę skonfigurować jako klawisze wprowadzające



     Config Portb.0 = Input                                     'UP
     Config Portb.1 = Input                                     'DOWN
     Config Portb.2 = Input                                     'Zatwierdzenie i start

    '**********************************************************************************************************



    Config Timer1 = Timer , Prescale = 8
                                                                 'deklaracja timera jako czasomierza

            Pinb.3 = 0                                          'ustawienie potu wyjscia

    '*************************************************************************************************
      'Stan początkowy pinów wykorzystywanych do obsługi klawiszy UP, DOWN, Start
     Pinb.0 = 1
     Pinb.1 = 1
     Pinb.2 = 1
     '************************************************************************************


    On Timer1 Przerwanie_co_2ms

    Impulsy Silnika Alias Portb.3

    Enable Interrupts                                           'odblokowanie globalne przerwan
    Enable Timer1                                               'odblokowanie przerwania od przepełnienia timer0
    Timer1 = 34286
       T = 1                                                    ' to mam zamiar podawać z klawiszy UP DOWN
      X = 10                                                    'to też mam zamiar podawać z klawiszy UP DOWN
      Y = X



    Do
    Loop
    End

      '*********************************************************************** Przerwanie ********************************************************************


    Przerwanie_co_2ms:

     Incr L
     Locate 2 , 7
     Lcd L

      If L = 2108 Then
        Stop Timer1
          End If

      If L = X Then
        Stop Timer1
          Wait T
           X = X + Y
            Start Timer1

      Else
        Toggle Impulsy Silnika
            End If


     Locate 1 , 1
     Lcd "Ile przep.Timera1"
    Return

    Obecnie programik pracuje , jednak wlasnie bez obsługi klawiszy, kwarcu nie ma zewnetrznego, pracuje narazie na generatorze wewnętrznym. Wiem wiem mało dokładny tak jak i instrukcja WAIT ale to się zmieni potem.
  • Poziom 38  
    W dobrym kierunku idziesz- ale pozostają Ci zadry.
    Skoro już masz przerwanie co 2ms- to niech inkrementuje tylko flagi.
    A w pętli głównej można zrobić-
    if flaga_1>0 then silnik
    ...
    flaga_1=0

    if flaga_2> 100 then wyświetlacz
    ...
    flaga_2=0

    itd.
  • Poziom 15  
    Ciąg dalszy bojów z tym kodem i jeżeli to możliwe prozba o dalszą pomoc.
    Wiec tak , obecnie podaję czas pracy silnika X1 oraz czas postoju T(klawiszami zwiększam albo zmniejszam parametry X1 oraz Y).
    Generalnie będzie to jeden z dwóch trybów pracy, drugi ma być z ciągłą regulacją płynną klawiszami UP i Down.
    O co teraz proszę - o pomoc w skonstruowaniu tak jakby jeszcze jednego okna menu NAD tym co mam Menu . Siedzę i nic mi nie wychodzi , próbuję z pętlami , próbuję z SELECT Case ale chyba nie rozumie samej istoty zadziałania procedury CASE.W sumie to pewnie od tego powinienem zacząć ale jakoś tak wyszło , że najpierw chciałem "poganiać" ten silniczek krokowy i zobaczyć czy w ogóle uda mi sie zapanować prockiem nad jego sterowaniem. Dopiero potem pomyślałem o jakimś menu. Zdaje sobie sprawę, że kod może być zagmatwany i może dało by sie go uprościć - proszę o wyrozumiałość , to pierwszy tak większy jak na mnie projekcik.Podsumowując zaplanowałem to tak:
    1) MENU GŁÓWNE
    up-praca cykliczna
    down - praca ciągła
    2)MENU CYKLICZNE(podrzędne dla Menu głównego)
    a)ustawienie parametru X1
    up-zwiększ parametr X1
    down-zmniejsz parametr X1
    Zat1- zatwierdzenie ustawień i przejście do
    b)ustawienie par T
    up- zwiększanie
    down-zmniejszanie
    zat2-zatwierdzenie i start silnika.
    3)MENU PRACA CIAGŁA (podrzędne dla MENU GŁOWNEGO)
    Obecnie mam tak jakby zrobione działające całe MENU CYKLICZNE, brak mi właśnie tego MENU GŁÓWNEGO
    Oto kod
    Code:

    $regfile = "attiny2313.dat"                                 'rejestry mikrokontrolera atmega8

    Config Lcd = 16 * 2

    Config Lcdpin = "tutaj konfiguracja pracy lcd"


    Cursor Off
    Cls

      Dim L As Word                                             'zmienna ilosci przepelnien Timera1
      Dim Y As Word                                             'druga zmienna dodawana do czasu pracy
      Dim T As Word                                             'zmienna określajaca czas wstrzymania  Timera1
      Dim Z As Word                                             'stan klawiatury
      Dim X1 As Word                                            'Ilość Przepełnień Timera1



       Declare Sub Skok
       Declare Sub Skok1

    '**********************************************************************



     Config Portb.3 = Output


     Config Portb.0 = Input                                     'UP
     Config Portb.1 = Input                                     'DOWN
     Config Portb.2 = Input                                     'zatwierdzanie
     Config Portd.5 = Input                                     'start
     Config Portb.4 = Input
    '*******************************************************************



    Config Timer1 = Timer , Prescale = 8
                                               'deklaracja timera jako czasomierza

      Pinb.3 = 0                                                'ustawienie potu wyjscia

    '********************************************************************
      'Stan początkowy pinów wykorzystywanych do obsługi klawiszy UP, DOWN, Start
     Pinb.0 = 1                                                 'up
     Pinb.1 = 1                                                 'down
     Pinb.2 = 1                                                 'zatwierdzenie1
     Pind.5 = 1                                                 'zatwierdzenie2
     Pinb.4 = 1                                                 'wolny nie osadzonu żadną funkcją

     '**************************************************

     Timer1 = 34286

      T = 0
      Z = 0                                                     'wstępne ustawienia zmiennych
      X1 = 150



    '*******************************************************************



    Impulsy Silnika Alias Portb.3


     '*****************************************************************************

      On Timer1 Przerwanie_co_2ms
       Enable Interrupts                                        'start timer1
        Enable Timer1
         Stop Timer1

    '**********************************************************************

    Do

     If Z = 0 Then
      Call Skok
       Else
        Call Skok1
         End If
    Loop                                                        'PĘTLA  GŁÓWNA
    End

    '***********************************************************************

    '---------------------------------------------Zmienna X1czas pracy---------------
    Sub Skok

    If Z = 0 Then
     Locate 1 , 1
      Lcd "Podaj ilosc krokow silnika"
       Locate 2 , 1
        Lcd X1 ,
         Locate 2 , 5
          Lcd "/400=obr"
           End If

      If Pinb.0 = 0 Then                                        'dodawanie ilości przepełnień
       If X1 < 999 Then
        Incr X1
         End If
          End If

      If Pinb.1 = 0 Then                                        'odejmowanie ilosci przepelnien
       If X1 > 100 Then
        Decr X1
         End If
          End If

      If Pinb.2 = 0 Then                                        'przejście do następnego podprogramu
       Cls
        Z = 1
         End If

    End Sub
    '------------------------------------------Zmienna  T-czas postoju-----
     Sub Skok1
    If Z = 1 Then
     Locate 1 , 1
      Lcd "Czas postoju w sek."

    Locate 2 , 1
     Lcd T
      End If

    If Pinb.0 = 0 Then                                          'dodawanie ilości T
    If T < 999 Then
      Incr T
     End If
      End If

    If Pinb.1 = 0 Then                                          'odejmowanie ilosci T
       If T > 1 Then
    Decr T
       End If
       End If

    If Pind.5 = 0 Then                                          'start odliczania impulsow
     Cls
     Z = 2

    If Z = 2 Then
      Y = X1
       Start Timer1
        End If                                                  'start timera1
         End If


      End Sub


      '************************* Przerwanie ***********************************


    Przerwanie_co_2ms:

     Incr L
     Locate 2 , 1
     Lcd L

      If L = 4801 Then
      Cls
      Lcd "KONIEC PRACY"
        Stop Timer1


          End If

      If L = X1 Then
        Stop Timer1
          Wait T
           X1 = X1 + Y
            Start Timer1

      Else
        Toggle Impulsy Silnika
            End If


     Locate 1 , 1

     Lcd X1
    Return

    Być może nie zmieści sie to w przyszłości w ten procek, bedę to musiał przeportować np na Atmega 8 , zobaczymy. Czas tego timera1 też potem bedę dobierał do samego silnika, obecnie jest taki podział abym mógł zaobserwować miganie diody led.
    Mam jeszcze tylko jeden mały problem z działaniem tego programu , taki raczej kosmetyczny ale drażniący. Jeżeli powiedzmy zwiekszam X1 i zaczynam od liczby 2 cyfrowej np 50 a kończę na 3 cyfrowej np 150, to podczas ujmowania wartości tego parametru , na lcd widzę że nie zchodzi do np 50 tylko w momencie przechodzenia z liczby 3 cyfrowej na 2 cyfrową , na wyświeltaczu pojawia się 999 i odlicza od tego. Sam program chyba liczy sobie dobrze ale tak mi to sie wyświetla , nie wiem dlaczego.