Witam Wszystkich,
To mój pierwszy post na forum, jakoś jak do tej pory wszystkie odpowiedzi udawało się znaleźć.
Ale pojawił się następujący problem: Wykorzystuje ATmega8 do sterowania trzema serwami (jeden timer-jedno serwo). Z samym sterowaniem na przyciskach wszystko jest ok i nie to jest problemem. Nie wiem jak sobie poradzić z transmisją danych na SPI skoro Timer2 ma wyjście na wejściu MOSI a ATmega8 ma być ustawiona jako slave. Jeśli ma ktoś jakiś pomysł będę bardzo wdzięczny za pomoc.
Próbowałem zrobić to w taki sposób żeby DDRB timera ustawiać w przerwaniu jako wyjście, a przez pozostały czas mogło by służyć jako wejście dla SPI, ale niestety się nie sprawdza, symulacja w AVRStudio działa ale po wrzuceniu na uC niestety nie. Poniżej zamieszczam kod:
Program jeszcze bez SPI, ponieważ Timery w takim ustawieniu nie działają, ale jeśli zmienić odpowiednio miejsca oznaczone przez //# tzn. usunąć komentaż przy DDRB w port_init() a pozostałe elementy usunąć wszystko działa bez zarzutów.
To mój pierwszy post na forum, jakoś jak do tej pory wszystkie odpowiedzi udawało się znaleźć.
Ale pojawił się następujący problem: Wykorzystuje ATmega8 do sterowania trzema serwami (jeden timer-jedno serwo). Z samym sterowaniem na przyciskach wszystko jest ok i nie to jest problemem. Nie wiem jak sobie poradzić z transmisją danych na SPI skoro Timer2 ma wyjście na wejściu MOSI a ATmega8 ma być ustawiona jako slave. Jeśli ma ktoś jakiś pomysł będę bardzo wdzięczny za pomoc.
Próbowałem zrobić to w taki sposób żeby DDRB timera ustawiać w przerwaniu jako wyjście, a przez pozostały czas mogło by służyć jako wejście dla SPI, ale niestety się nie sprawdza, symulacja w AVRStudio działa ale po wrzuceniu na uC niestety nie. Poniżej zamieszczam kod:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define SetBit(x,y) x |= (1<<y)
#define ClrBit(x,y) x &= ~(1<<y)
#define NegBit(x,y) x ^= (1<<y)
unsigned char a;
volatile unsigned char x;
//ustawienia inicjujące porty
void port_init(void)
{
//DDRB=0B000001011; //#
DDRD=0x00;
PORTD=0x03;
}
//ustawienia inicjujące timery
void timer_init(void)
{
//Timer 0
TCCR0=0x04; //Prescaler /256
TCNT0=0xE8;
//Timer 1
TCCR1A=0x00;
TCCR1B=0x04; //Prescaler /256
TCNT1H=0xFF;
TCNT1L=0xE8;
//Timer 2
TCCR2=0x06; //Prescaler /256
TCNT2=0xE8;
//Zezwolenie na przerwania od T1,T2,T3
TIMSK|=_BV(TOIE0)|_BV(TOIE1)|_BV(TOIE2);
}
//funkcje przerwań
SIGNAL (SIG_OVERFLOW0)
{
if(!(a & 0x01) )
{ DDRB|=(1<<0); //#
TCCR0=0x00;
SetBit(PORTB,0);
TCNT0=x;
TCCR0=0x04;
a=PORTB;
}
else if((a & 0x01))
{
TCCR0=0x00;
ClrBit(PORTB,0);
TCNT0=x;
TCCR0=0x04;
a=PORTB;
DDRB&=~(1<<0);//#
}
}
SIGNAL (SIG_OVERFLOW1)
{
if(!(a & 0x02) )
{
DDRB|=(1<<1);//#
TCCR1A=0x00;
TCCR1B=0x00;
SetBit(PORTB,1);
TCNT1H=0xFF;
TCNT1L=x;
TCCR1A=0x00;
TCCR1B=0x04;
a=PORTB;
}
else if((a & 0x02))
{
TCCR1A=0x00;
TCCR1B=0x00;
ClrBit(PORTB,1);
TCNT1H=0xFF;
TCNT1L=x;
TCCR1A=0x00;
TCCR1B=0x04;
a=PORTB;
DDRB&=~(1<<1); //#
}
}
SIGNAL (SIG_OVERFLOW2)
{
if(!(a & 0x08) )
{
DDRB|=(1<<3);//#
TCCR2=0x00;
SetBit(PORTB,3);
TCNT2=x;
TCCR2=0x06;
a=PORTB;
}
else if((a & 0x08))
{
TCCR2=0x00;
ClrBit(PORTB,3);
TCNT2=x;
TCCR2=0x06;
a=PORTB;
DDRB&=~(1<<3);//#
}
}
//funkcja inicjująca
void init_devices(void)
{
//zatrzymanie przerwań na czas uruchomienia
cli(); //wyłączenie przerwań
//inicjacja f-cji
port_init();
timer_init();
//inicjacja rejestrów
MCUCR = 0x00;
GICR = 0x00;
//zezwolenie na przerwania
sei();
}
int main (void)
{
a=0;
x=0xBA; //Położenie środkowe
//funkcja inicjująca
init_devices();
while(1)
{
///Ustawienia przycisku///
if(!(PIND & 0x01))
{
_delay_ms(10);
if(!(PIND & 0x01))
{
x++;
}
if(x>0xE9)
{
x=0xE9;
}
}
if(!(PIND & 0x02))
{
_delay_ms(10);
if(!(PIND & 0x02))
{
x--;
}
if(x<0x8B)
{
x=0x8B;
}
}
}
return(1);
}
Program jeszcze bez SPI, ponieważ Timery w takim ustawieniu nie działają, ale jeśli zmienić odpowiednio miejsca oznaczone przez //# tzn. usunąć komentaż przy DDRB w port_init() a pozostałe elementy usunąć wszystko działa bez zarzutów.