Skocz do zawartości

[C]Serwa po raz kolejny


Pomocna odpowiedź

Napisano

Witam,

Jako kolejny początkujący z serwami, mam problem ze sterowaniem z poziomu timera w atmedze8. Oto kod:

#include <avr/io.h>
#include <util/delay.h>

int main()
{
DDRD = 0xFF;

TCCR1A |= (1<<COM1A1) | (1<< WGM11) ; // Set up timer/mode

TCCR1B |=   (1<<WGM13)|(0<<WGM12)|(1<<CS11) ; //prescaler na 8


ICR1  = 20000;// Dla kwarcu 16MHz

while(1)
{
	OCR1A =  500;		//co sekunde zmienia pozycje serwa
	_delay_ms(1000);
	OCR1A =  300;
	_delay_ms(1000);
}
}

Przy takim kodzie z pinu PB1 nie wychodzi w ogóle żaden sygnał.

Z góry dzięki za pomoc,

kram

TCCR1B |=   (1<

Nie możesz jednocześnie ustawiać i kasować bitów w jednym poleceniu.

Jeśli chcesz skasować bit WGM12, zrób tak:

TCCR1B &= ~(1<

pardon, zamiast 0 miala tam byc jedynka. Niestety problem pozostaje taki sam.

wrzucam poprawiony kod:


#include <avr/io.h>
#include <util/delay.h>

int main()
{
DDRD = 0xFF;

TCCR1A |= (1<<COM1A1) | (1<< WGM11) ; // Set up timer/mode

TCCR1B |=   (1<<WGM13)|(1<<WGM12)|(1<<CS11) ; //prescaler na 8


ICR1  = 20000;// Dla kwarcu 16MHz

while(1)
{
	OCR1A =  500;		//co sekunde zmienia pozycje serwa
	_delay_ms(1000);
	OCR1A =  300;
	_delay_ms(1000);
}
}

Na OC1A nadal nic nie ma...

Zupelnie bez zmian. Na OC1A nadal cisza.

Aktualny kod:


#include <avr/io.h>
#include <util/delay.h>

int main()
{
DDRD = 0xFF;

TCCR1A |= (1<<COM1A1) | (1<< WGM11) ; // Set up timer/mode

TCCR1B |=   (1<<WGM13)|(1<<WGM12)|(1<<CS11) ; //prescaler na 8


ICR1  = 10000;// Dla kwarcu 16MHz

while(1)
{
	OCR1A =  1000;		//co sekunde zmienia pozycje serwa
	_delay_ms(2000);
	OCR1A =  300;
	_delay_ms(1000);
}
}

A dlaczego uwazasz ze zmiana ICR1 na 10000 mialaby pomoc? przeciez przy kwarcu 16 i prescalerze 8 potrzeba 20000, zeby sygnal mial 50hz, nie?

A dlaczego uwazasz ze zmiana ICR1 na 10000 mialaby pomoc? przeciez przy kwarcu 16 i prescalerze 8 potrzeba 20000, zeby sygnal mial 50hz, nie?

Masz rację, wkradł mi się jakiś "chiński błąd" 😖

Ale tak licząc: 16MHz / 8 = 2 000 000...2 000 000 / 50Hz = 40000.

Spróbuj ustawić preskaler na 64 i wtedy wpisz do ICR1 5000. I do OCR1 np. 500.

kurde, bez zmian... Jakim cudem?!

Aktualny kod:

#include <avr/io.h>
#include <util/delay.h>

int main()
{
DDRB = 0xFF;

TCCR1A |= (1<<COM1A1) | (1<< WGM11) ; // Set up timer/mode

TCCR1B |=   (1<<WGM13)|(1<<WGM12)|(1<<CS11)| (1<<CS10) ; //prescaler na 64


ICR1  = 5000;// Dla kwarcu 16MHz

while(1)
{
	OCR1A =  500;		//co sekunde zmienia pozycje serwa
	_delay_ms(1000);
	OCR1A =  1000;
	_delay_ms(1000);
}
}

A nie wiem, nie trzeba dodać jakiegoś kodu, o którym nie wiem, żeby "przekierować" sygnał do OC1A?

[ Dodano: 11-03-2012, 11:19 ]

hah, dobra, mój błąd, znowu niedopatrzenie durne w kodzie, zamiast DDRB było DDRD. Po poprawce sygnał wychodzi, ALE serwa w ogóle na niego nie reagują ;l Tzn, jedno serwo jedzie do końca, reszta w ogóle nie chce ruszyć. Jakieś sugestie?

Do zasilania serwa uzywam zewnetrznego zasilacza 6V.

[ Dodano: 11-03-2012, 19:04 ]

Probowalem jeszcze tego kodu, dla wewnetrznego oscylatora 1Hz:



#define F_CPU 1000000L

#include <avr/io.h> 
#include <util/delay.h> 


int main()
{ 
DDRB = 0xff; //konfiguracja portow  
TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); //tryb pracy licznika(15), ustawienie prescalera na 1, 
TCCR1B = (1<<CS10)|(1<<WGM12)|(1<<WGM13); //ustawienie wyjścia z licznika
ICR1 = 20000; //ustawienie okresu na 20ms(czestotliwosc 50Mz)

OCR1A = 2000; //określenie czasu impylsu 
}

Ta sama sytuacja, jedno serwo jedzie do konca, dwa w ogole nie reaguja. Serwa zakladam ze sprawne, swiezo odpakowane ze strony conrad.pl. Bardzo prosze o pomoc, mecze sie z tym juz od paru dni...

Ile ty masz tych serw? Dwa czy trzy?

Zakładam, że dwa.

Jak je podłączasz? Czy obydwa są podłączone do OC1A(PB1), czy jedno do OC1A(PB1) a drugie do OC1B(PB2)?.

Jeżeli podłączasz pierwsze serwo do OC1A a drugie do OC1B to musisz wprowadzić jakąś wartość również do OCR1B, a nie tylko do OCR1A.

Bo teraz to na OC1A masz sygnał PWM o wypełnieniu 2000/20000 (10%), a na OC1B masz sygnał PWM o wypełnieniu 0/20000 (0%).

W jaki sposób to wszystko zasilasz?? Jeżeli elektronikę zasilasz z jednego zasilacza, a serwa z drugiego to musisz połączyć ich masy ze sobą.

  • Lubię! 1
Ile ty masz tych serw? Dwa czy trzy?

Jeżeli elektronikę zasilasz z jednego zasilacza, a serwa z drugiego to musisz połączyć ich masy ze sobą.

O to chodzilo 😉 dzieki wielkie za pomoc, pozdrawiam!

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...