Skocz do zawartości

Obsługa serwa z timerem [AVR]


Byciek94

Pomocna odpowiedź

cześc,
postanowiłem napisać prosty programik do obsługi jednego serwa.

o to kod:

#include

int main()

{

DDRB=0x00;

TCCR1B|=_BV(CS10);

int licznik = 0;

PORTB&=~_BV(1);

while(1)

{

if(TCNT1==20000)

{PORTB|=_BV(1);

TCNT1=0;

licznik=1;

}

while(licznik==1)

{

if(TCNT1==2500)

{PORTB&=~_BV(1);

TCNT1=0;

licznik=0;

}}}}

poprzez drugie spr. stanu licznika wybieram długość sygnału. wszystko niby działa ale nie wiem czemu na wyjści PB1 poprawny sygnał mam tylko dla wielokrotności 300(600,900,1200,1500,1700,2100,2400,2700) Może ktoś mi podpowiedzieć oc jest tego przyczyną. Procek to Atmega 8:)

__________

Komentarz dodany przez: Treker

Link do komentarza
Share on other sites

Na początek zastanów się jak długo Twój timer jest w każdym stanie tzn. przez ile czasu jest w nim liczba 2500 lub 20000. Przez jeden okres zegara procesora? To znaczy przez czas wykonania słownie jednej instrukcji? Skąd masz pewność, że będzie to własnie ta instrukcja która pobiera zawartość timera w celu porównania ze stałą? Mógłbyś to kulawo obejść przez wykorzystanie operatora >= zamiast == (wtedy nawet przeoczenie stanu 2500 spowoduje wykonanie if-a chwilę później), ale timerów nie używa się w ten sposób. Czyż nie bardziej elegancko jest załadować mu jakąś wartość (np. -20000) i poczekać aż sam zgłosi odpowiednim sygnałem (np. przepełnienia), że przeszedł z 0xFFFF na 0x0000? A jeszcze lepiej załadować spodziewaną wartość do któregoś rejestru OCRx i poczekać na sygnał komparacji, potem załadować następną spodziewaną wartość (bez przeładowywania lub zerowania timera) i znów poczekać itd... Przy korzystaniu z przepełnień (flaga TOVx) czy komparacji (flagi OCFxy) słowo "poczekać" możesz zawsze zastąpić zwrotem "obsłużyć przerwanie".

  • Lubię! 1
Link do komentarza
Share on other sites

dzięki za odpowiedź🙂

napisałem programik który działa na trybie CTC i ustawia serwo na jedną z 10 pozycji, po czym przechodzi do nastopnej. oto kod:

#include

#include

int main()

{

TCCR1B |= (1 << WGM12); // Ustawia timer w tryb CTC

TCCR1B |=_BV(CS10);//ustawienie licznika na 1MHz

volatile int licznik=0;

volatile int n;

volatile int k;

volatile int puls[11]={400,560,740,960,1180,1400,1620,1840,2060,2280,2500};

volatile int czestotliwosc=2000;

while(1){

for(n=0;n<10;n++)

{

for(k=0;k<100;k++){

while(licznik==0){

OCR1A=puls[n];

if(TIFR & (1 << OCF1A)){

PORTB&=~_BV(1);

OCR1A=20000;

TIFR = (1 << OCF1A);

licznik=1;

}}

while(licznik==1){

if(TIFR & (1 << OCF1A))

{PORTB|=_BV(1);

TIFR = (1 << OCF1A);

OCR1A=czestotliwosc;

licznik =0;

}

}

}

_delay_ms(200);

}}}

i tu mój problem, jak widać kod jest troche zawiły, i zastanawiam sie czy nie można tego zrobić w jakiś łatwiejszy sposób. Ktoś coś ? 🙂

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.