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

[Atmega16] [Atmega16][C] Sterowanie silnikiem DC i zliczanie impulsów timerem0

fasset 13 Lip 2012 10:25 2516 12
REKLAMA
  • #1 11100674
    fasset
    Poziom 13  
    Witam ponownie.

    Chcę zrobić sterowanie silnikiem prądu stałego za pomocą mikrokontrolera Atmega16a. Sterowanie ma się odbyć za pomocą zmiennego sygnalu PWM - to dobrze rozumiem i zaprogramowałem.
    Prędkość obrotów będzie regulowana za pomocą przycisku. Pozostaje problem zliczania impulsów - na początku próbowałem programowo niestety bez oczekiwanego skutku.
    Do zliczania będzie wykorzystany licznik timer0.
    Pomysł odnośnie realizacji tego to ustawienie nóżki licznika OCO (PB3) w stan wysoki + przycisk zwarty do masy. Po każdym włączeniu przycisku pojawi się stan niski na PB3 co ma zostać zliczone. Z dokumentacji uznałem, że najlepiej to będzie zrobić za pomocą "opadającego zbocza" (ustawienie bitów CS02 i CS01 w rejestrze TCCR0. Jeżeli to zły pomysł to proszę o wyprowadzenie mnie z błędu.

    1-Co ustawić aby licznik liczył do określonej liczy np. do 10 (zamiast 255)?
    2- Czy to jaką licznik ma wartość można sprawdzić programowo np. if(OCR0==10)?
  • REKLAMA
  • #2 11100702
    dondu
    Moderator na urlopie...
    1. Przycisk do zliczania obrotów silnika? Ile maksymalnie obrotów na minutę będzie miał ten silnik?
    2. Piszesz, że miałeś już program, ale nie działał prawidłowo - może go pokaż + schemat Twojego układu.
  • REKLAMA
  • #4 11100778
    Konto nie istnieje
    Poziom 1  
  • #5 11100794
    LordBlick
    VIP Zasłużony dla elektroda
    Użyj rejestru od porównania wartości licznika OCR0. Wtedy jak ustawisz, że ma to powodować przerwanie, w odpowiedniej chwili zadziała... ;)
    dejmos napisał:
    ad 1. wpisuj zawsze do licznika 245 wtedy będzie liczył tylko do 10 (255 - 245 = 10)
    Owszem można i tak, aczkolwiek jest to raczej workaround(praca dookoła).
  • #6 11100806
    fasset
    Poziom 13  
    dondu napisał:
    1. Przycisk do zliczania obrotów silnika? Ile maksymalnie obrotów na minutę będzie miał ten silnik?
    2. Piszesz, że miałeś już program, ale nie działał prawidłowo - może go pokaż + schemat Twojego układu.


    1 - chodziło o to, że przycisk ma zmieniać stan licznika, następnie licznik będzie zmieniał wypełnienie PWM a tym samym napięcie będzie regulowane od ok. 1V do 5V czyli wpłynie na prędkość obrotów.
    2 - To było kombinowanie, szczerze to nie dziwie się, że nie działało :) Tutaj spróbowałem inną metodą. Przycisk na PA1 )zwarty do masy, na wyjściu OC0 (PB3) pojawiało się napięcie albo niskie, albo wysokie - płynna regulacja to nie była :)
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    dondu napisał:


    A nie lepiej przy pomocy INT0 lub INT1?
    ad 1. wpisuj zawsze do licznika 245 wtedy będzie liczył tylko do 10 (255 - 245 = 10)
    ad 2. można

    Spróbuje coś doczytać o wejściach, o których napisałeś jak nie uda się zrobić tego w powyższy sposób. Dlaczego polecasz tą metodę?

    EDIT: Dzięki za szybkie odpowiedzi

    Dodano po 4 [godziny] 16 [minuty]:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Tak jak wspomniałem do wyjścia PB3 (OC0) jest podłączony przycisk zwarty do masy, a wyjście ustawione w stan wysoki. Dlaczego program nie działa tak jak powinien? Tzn dlaczego diody na PORTD świecą się cały czas mimo włączania przycisku (licznik powinien zliczać zbocza opadajace) ?
  • REKLAMA
  • #7 11103548
    LordBlick
    VIP Zasłużony dla elektroda
    fasset napisał:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Tak jak wspomniałem do wyjścia PB3 (OC0) jest podłączony przycisk zwarty do masy, a wyjście ustawione w stan wysoki. Dlaczego program nie działa tak jak powinien? Tzn dlaczego diody na PORTD świecą się cały czas mimo włączania przycisku (licznik powinien zliczać zbocza opadajace) ?
    1. Przycisk powinieneś podłączyć do wejścia T0 (PB0). Niestety nie widzę zdjęcia, aby to zweryfikować.
    2. Ustaw początkowa wartość licznika mniejszą od 0xFA(różnica będzie wynosiła konieczną ilość naciśnięć), inaczej natychmiast ustawi wszystkie bity portu D na wysoki.
  • REKLAMA
  • #8 11108515
    fasset
    Poziom 13  
    Niestety dałem też przycisk na PB0 i nie działa dalej.
    Wiem, że diody z PORTD odrazu się palą, ale o to też mi chodzi. Jeżeli by zgasły oznaczało by to, że licznik zwiększa swoją wartość.
    Podejrzewam, że chodzi o błędy w kodzie?
  • #9 11110141
    fasset
    Poziom 13  
    Z powyższymi problemami już się uporałem.
    Nurtuje mnie jeszcze jedno (rozwiązałem to w inny sposób):
    Dlaczego ten fragment kodu:
    if(TIFR&0x20)	{
    		TIFR &= 0x20;
    		TCNT0=0xfa;
    	} 

    Powoduje zliczanie licznika tylko do 253?
  • #11 11111172
    fasset
    Poziom 13  
    Przeczytałem, że bit TOV0 o adresie 0x20 w rejestrze TIFR ustawia się gdy występuje przepełnienie licznika - jest to tzw. 9 bit licznika. Chciałem to w ten sposób zapętlić żeby zliczało od 250 do 255. Zlicza cały czas od 250 do 253. - pytam z ciekawości problem rozwiązałem inaczej.

    Kolejny napotkany problem:
    Silnik, który ma być regulowany jest na napięcie od 4.5 V. Port OC1A ustawiony w tryb PWM generuje max. 3 V co skutkuje tym, że silnik w ogóle nie chce ruszyć.
    Dlatego próbuje dołączyć napięcie z zewnątrz wg tego schematu: (Tranzystor BC548)
    http://www.robotroom.com/PWM5.html
    Układ podłączony w ten sposób nie rusza silnikiem. Podejrzewam, że to problem mas. Mikrokontroler jest zasilany z USB, a silnik z baterii 4.5 V. W układzie są dwie masy, jak rozwiązać ten problem?

    Pozdrawiam
  • #13 11113011
    LordBlick
    VIP Zasłużony dla elektroda
    fasset napisał:
    Przeczytałem, że bit TOV0 o adresie 0x20 w rejestrze TIFR ustawia się gdy występuje przepełnienie licznika
    Bit nie ma adresu, ma go tylko rejestr TIFR. Nawet w asemblerze nie ma potrzeby sprawdzania adresów i numerów bitów, to już jest zdefiniowane w pliku nagłówkowym i wystarczy używać:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Zwykle jednak w takich sytuacjach używa się przerwania i w jego obsłudze nie ma potrzeby sprawdzać tego bitu(na 100% przy wystąpieniu przerwania ISR(TIMER0_OVF_vect) jest ustawiony), ani go zerować, bo robi to za nas sprzęt. Natomiast zabawa poza przerwaniem nie ma głębszego sensu, bo pomiar czasu jest raczej niedokładny.
    BTW. Kod C w tagu syntax jest zdecydowanie czytelniejszy. [syntax=C]Kodzik tu...[/syntax]
REKLAMA