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

[C] [AVR] Niechciane wyjście z pętli

drednot 29 Gru 2008 20:09 1158 4
REKLAMA
  • #1 5920224
    drednot
    Poziom 15  
    Witam. Tworzę program który będzie odpowiadał za wysłanie adresu i odebranie danych z przetwornika ADC przy pomocy transmisji SPI.
    Oto on:


    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    
    void SPI_MasterInit(void)
    	{
    	// Set MOSI and SCK oraz SS output, all others input 
    	DDRB |= (1<<DDB2)|(1<<DDB1)| (1<<DDB0);
    	// Enable SPI, Master, set clock rate fck/16 
    	SPCR |= (1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<SPR0);
    	}
    
    
    
    
    void SPI_M_T(char cData)
    	{
    	/* Start transmission */
    	SPDR = cData;
    	/* Wait for transmission complete */
    	while(!(SPSR & (1<<SPIF)));
    	
    	}
    
    
    int main(void)
    {
    	//PORTD |= (0<<PD7); //led ON
    	//DDRD |= (1<<DDD7); //PD7 jako wyjście
    	//PRR0 = (1<<PRTWI) | (1<<PRADC);  //wylaczymy twi i adc
    	
    		/* ---------generator-------- */
    	DDRB |= (1<<DDB4) ;			 //PB4 (OC.2A) jako wyjście
    	OCR2A = 100; 					//przepełnienie przy 2
    	TIMSK2 |= (1<<OCIE2A) | (0<<TOIE2); //zezwolenie na przewania od porównania i przepełnienia
    	TCCR2A |= (1<<COM2A0) |(1<<WGM21) ; // toggle OC2A; tryb CTC
    	TCCR2B |= (0<<CS22)   |(1<<CS21)  |(1<<CS20) ; //presk 1
    		
    	SREG |= (1<<SREG_I);  // 	
    		
    	
    	while(1)
    	{	
    		PORTB &= ~(_BV(0));  //ss = 0
    		SPI_MasterInit();
    		SPI_M_T(0b00001000);
    
    		//PORTB |= (_BV(0));  //ss = 1
    	}
    }
    


    W tle działa generator sprzętowy (wy OC.2A) na timerze 2 w trybie CTC i to jest OK. Natomiast chciałbym aby program nie wychodził mi z pętli while a tak się dzieje po wysłaniu danych SPI. Jak się z tym uporać?
    Pracuję w symulatorze AVR Studio.
    Pozdrawiam
    :)
  • REKLAMA
  • #2 5920336
    snow
    Poziom 31  
    Daj return 0; po while
  • REKLAMA
  • #3 5920413
    drednot
    Poziom 15  
    Wstawiałem w miejscu XXX i YYY i nic. Tak się zatanawiam od dwóch dni, dlaczego po wysłaniu danych kasowana jest flaga SREG_I? Bezpośrednio po wyjściu z
     void SPI_M_T(char cData) 

    Może to dlatego program wskakuje do main'a?


    
    while(1)
    	{	
    	        PORTB &= ~(_BV(0));  //ss = 0
    		SPI_MasterInit();
    		SPI_M_T(0b00001000);
    
    	
    		XXX
    	}
    YYY
    }
    



    PS jak w procedurze
     void SPI_M_T(char cData) 
    dopiszę coś po "czekaniu na koniec nadawania" to nie jest to wykonywane.
  • REKLAMA
  • #5 5920603
    drednot
    Poziom 15  
    Problemem było ustawienie bitu SPIE w rej. SPCR. Mój błąd.
    Pozdrawiam :)

    Dodano po 3 [godziny] 32 [minuty]:

    Troszkę pospieszyłem się z wnioskami. To nie ten parszywy bit był problemem. Jednocześnie jak go zmieniłem, dodałem również większą liczbę do licznika dla generatora.
    Problem jest taki, że każde przerwanie od porównania kasuje flagę SREG_I. W tym momencie program wychodzi do main'a i ustawia jeszcze raz timer2.
    Problem jest poważny bo to licznik 2 (czyli ten generator sprzętowy) ma pracować z f=4MHz i będzie zakłócał transmisję. Można jakoś to ominąć?
    :( :morning:
REKLAMA