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

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.