logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega162][WinAVR] Timer i odbieranie danych po SPI

thenkles 16 Cze 2008 20:19 2313 2
REKLAMA
  • #1 5253630
    thenkles
    Poziom 11  
    Witam, buduję sobie układzik, mający sterować diodą RGB (za pomocą PWM) na podstawie danych odebranych przez interfejs SPI (mikrokontroler działa jako SPI Slave). Napisałem program, w którym w nieskończonej pętli odbierane są 3 bajty, a w przerwaniu timera ustawiane jest odpowiednie wypełnienie dla diod. Jednak efekty działania programu są jakieś bezsensowne. Oto kod:

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    
    #define DDR_SPI DDRB
    #define DD_MISO 6
    #define DD_MOSI 5
    #define DD_SCK  7
    #define DD_SS   4
    
    #define TIMER3_INIT 62500
    
    char r1, g1, b1;
    
    char SPI_SlaveReceive(){
    	while(!(SPSR & (1<<SPIF)));
    	return SPDR;
    }
    
    ISR(TIMER3_OVF_vect){
    	TCNT3=TIMER3_INIT;
    	
    	OCR2=255-g1;
    	OCR0=255-b1;
    	OCR1AL=r1;
    }
    
    int main(){
    
    	r1=0;
    	g1=0;
    	b1=0;
    	
    	OCR2=255;
    	OCR0=255;
    	OCR1AL=0;
    
    	DDRB=3;
    	DDRD=255;
    	PORTB=252;
    	PORTD=0;
    
    	TCNT2=0x00;
    	TCCR2=0x73;
    
    	TCNT0=0x00;
    	TCCR0=0x73;
    
    	TCNT1H=0x00;
    	TCNT1L=0x00;
    
    	TCCR1B=0x01;
    	TCCR1A=0x81;
     
    	TCCR3A=0b00001100;
    	TCCR3B=0b00000101;
            
    	TCNT3=TIMER3_INIT;
            
    	ETIFR|=(1<<TOV3);
    	ETIMSK|=(1<<TOIE3);
     
    	sei();
    	
    	DDR_SPI|(1<<DD_MISO);
    	SPCR=(1<<SPE);
    	
    	
    	while(1){
    
    		r1=SPI_SlaveReceive();
    		g1=SPI_SlaveReceive();
    		b1=SPI_SlaveReceive();
    
    	}
    
    	return 0;
    }
    


    Na wyjściu nie dostaję nic. Pomyślałem, że albo źle działa transmisja SPI, albo w przerwaniu nie działa ustawienie wypełnienia. Postanowiłem to sprawdzić. Okazuje się, że jeżeli wrzucę zmianę wypełnienia do pętli, a usunę z przerwania, układ poprawnie ustawia jasność diod. Odbiór danych więc działa. Niestety, okazało się, że przy dodaniu (do oryginalnego kodu) na końcu pętli:
    
    r1=rand()%255;
    

    jasność koloru czerwonego przyjmuje losowe wartości (czyli tak, jakby można się spodziewać). Więc skoro działają dwie rzeczy osobno, to dlaczego nie chcą działać razem?

    Różnica jest tylko taka, że dane do zmiennych pochodzą z funkcji SPI_SlaveReceive(), a nie z funkcji rand(), więc nie mam pojęcia, skąd ta selekcja. Z góry dziękuję za jakiekolwiek pomysły rozwiązania problemu.

    P.S. Dopiero teraz zauważyłem nowy podział forum. Więc jeśli mój post tutaj nie pasuje, to proszę o przesunięcie do AVR.
  • REKLAMA
  • #3 5254745
    thenkles
    Poziom 11  
    Ach, taki bajer... :D Dzięki, teraz działa ;)
REKLAMA