Skocz do zawartości

[C] Obsługa dwóch serwomechanizmów przez timery w ATmega8


Defozo

Pomocna odpowiedź

Witajcie drodzy forumowicze!

Zwracam się do Was z problemem poprawnego ustawienia timerów w mikrokontrolerze ATmega8.

Chciałbym sterować jednocześnie dwoma serwomechanizmami, a przy tym jednocześnie odbierać komendy przez USART.

Linie sygnałowe serwomechanizmów podłączone są do pinów nr 15 (PB1 - OC1A) i 16 (PB2 - OC1B) w mikrokontrolerze.

Napisałem taki oto kod:

/*
* Sterownik_Serwomechanizmu_do_rolety.c
*
* Created: 2013-06-27 20:12:02
*  Author: Defozo
*/ 

#define F_CPU 8000000UL// Clock Speed
#define FOSC 8000000UL// Clock Speed
#define BAUD 9600 //prędkość USARTa w bps
#define MYUBRR ( FOSC  + BAUD * 8UL  ) / (16UL * BAUD) -1
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

static char wiadomosc;

void USART_Init( unsigned int ubrr) //procedura inicjalizacji USARTa
{
/* Set baud rate */
UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXC);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}

int main(void)					//program główny
{
//Zmienne:
int i;						//zmienna pomocnicza (przy pętlach for)

//Inicjalizacja portów:
DDRB = 0x00;				//ustawia wszystkie piny B na wejścia (tymczasowo)
DDRD = 0x00;				//ustawia wszystkie piny D na wejścia
PORTD = 0x00;				//ustawia stan niski na portach D

//Inicjalizacja timerów:
TCCR1A |= (1<<COM1A1)|(1<< WGM11); //set up timer/mode
TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10); //prescaler na 64
ICR1  = 10000; //dla kwarcu 8MHz

//Inicjalizacja USARTa:
USART_Init(MYUBRR);			//inicjalizacja USARTA
sei();						//włączenie przerwań

   while(1)					//nieskończona pętla
   {

}
}

ISR(USART_RXC_vect)
{
wiadomosc=UDR;
if (wiadomosc == 'a') //Pierwsza roleta - na dół
{
	DDRB = 0xFF;
	OCR1A =  20;
}
if (wiadomosc == 's') //Pierwsza roleta - do góry
{
	DDRB = 0xFF;
	OCR1A =  250;
}
if (wiadomosc == 'd') //Pierwsza roleta - STOP
{
	DDRB = 0x00;
}
if (wiadomosc == 'f') //Druga roleta - do góry
{
	DDRB = 0xFF;
	OCR1B = 20;
}
if (wiadomosc == 'g') //Druga roleta - na dół
{
	DDRB = 0xFF;
	OCR1B = 2000;
}
if (wiadomosc == 'h') //Druga roleta - STOP
{
	DDRB = 0x00;
}
}

Niestety nie spełnia on swojej roli.

Jak dobrze ustawić timery?

Z góry dziękuję,
Defozo

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

O ile serwomechanizm podłączony do OC1A (pin nr 15 - PB1 w ATmega8) działa w miarę okej (dlatego też wnioskuję, że komendy z USARTa są odczytywane poprawnie):

tzn. wyślę "a" na USART - roleta idzie na dół,
wyślę "s" na USART - roleta idzie do góry...

O tyle z drugim serwomechanizmem (podłączonym do OC1B - pin nr 16 - PB2 w ATmega8) - jest źle.

Komendy, które mają sterować OC1A, sterują też po części OC1B oraz komendy, które mają sterować OC1B, sterują OC1A, ale też jakoś inaczej, na OC1B roleta zawsze idzie do góry...

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.