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

SPI: Błędy w komunikacji ATmega8 z ATmega32 przy przesyłaniu 8 znaków

olo.d 28 Paź 2007 08:48 1196 2
REKLAMA
  • #1 4422061
    olo.d
    Poziom 15  
    Posty: 203
    No i kolejny problem tym razem z SPI, czy ktoś może sprawdzić mi mój listing?
    komunikacja przez spi atmegi8 z atmega32, jak przesyłałem jeden znak wszystko grało jak chce przelać 8 to juz jakieś bzdury wyświetla.
    Program przy wywołaniu ma zamienić się zawartością tablicy dane_spi, czyli atmega8 przesyła swoja do atmegi32 a ten z kolei ma zadeklarowana tablice która przesyła do atmegi8. ale coś im to nie idzie.

    Slave ATmega8
    unsigned char dana_i;
    unsigned char dana_spi[8]={1,2,3,4,55,66,77,0};    
    bit flaga_spi_gotowe;
    
    void read_spi(void)
    {       
    	for(dana_i=0;dana_i<8;dana_i++)
    	{       
    		SPDR=dana_spi[dana_i];
     		flaga_spi_gotowe=1;
     		SPCR=0b11101000;
     		while(flaga_spi_gotowe==1)
     			#asm("nop") 
    	}
     	
    }         
    //----------------------------------------------------------- SPI interrupt service routine
    interrupt [SPI_STC] void spi_isr(void)
    {
    	dana_spi[dana_i]=SPDR;             
          	SPCR=0b01101000;
          	flaga_spi_gotowe=0;
    }
    


    Master ATmega32
    unsigned char dana_spi[8]={4,4,4,3,3,3,99,8};
    unsigned char dana_i;
    bit flaga_spi;
    
    // SPI interrupt service routine
    interrupt [SPI_STC] void spi_isr(void)
    {
    	dana_spi[dana_i]=SPDR;
    	SPCR=0b01111000;
    	flaga_spi=0;
    }
    
    // Declare your global variables here
    void send_spi(void)
    {
    	for(dana_i=0;dana_i<8;dana_i++)
    	{
    	flaga_spi=1;
    	SPDR=dana_spi[dana_i];
           	SPCR=0b11111000;
    	while(flaga_spi==1)
    		#asm("nop")   
    	}
    
    }      
  • REKLAMA
  • #2 4422662
    tomsyty

    Poziom 26  
    Posty: 696
    Pomógł: 102
    Ocena: 20
    Czy to jest avr-gcc? Jakoś nie kojarzę zapisu interrupt [SPI_STC] no i deklaracji zmiennej jako bit... W każdym bądź razie, jak masz zmienną globalną i przerwanie zmienia jej stan, który jest sprawdzany w pętli, to ta zmienna musi być zadeklarowana jako volatile. Poza tym twój program i tak zapętla się w oczekiwaniu na zakończenie nadawania / odebranie znaku, tak więc nie ma potrzeby stosowania przerwania
    SPDR = dana_spi[dana_i];
    while(!(SPSR & (1<<SPIF)));
    dana_spi[dana_i] = SPDR;
    

    to wszystko może być w pętli.
    Nie wiem czy piszesz w avr-gcc, tak więc nie wiem czy obowiązują w innych językach takie słowa jak volatile i takie traktowanie zmiennych.
    Konto firmowe:
    Tomasz Jędras (tomsyty)
    Wierzbowa 30a, Lubin, 59-300 | Tel.: 601XXXXXX (Pokaż) | Strona WWW: https://tomsyty.pl
  • #3 4422967
    olo.d
    Poziom 15  
    Posty: 203
    Co do zastosowanego programu to codevision, a mój kod trochę zmodyfikowałem i wygląda na to że działa bo przesyła sobie nawzajem tablice. Tylko nie wiem czego mimo zadeklarowanej tablicy w MASTER zamiast 4 odczytuje mi 255.
    Wygląda to tak że gdy dostanie rozkaz wyślij tablice:
    SLAVE wysyła 1,2,3 do MASTERA i master to zapisuje w tablicy. W tym samym czasie MASTER powinien wysłać 4,4,4 a wysyła 255,255,255 do SLAVE. Ale żeby było zabawniej to przy kolejnym rozkazie wyślij
    SLAVE wysyła 255,255,255 (logicznie i poprawnie) do MASTERA i master to zapisuje. W tym samym czasie MASTER wysyła 1,2,3. (100% poprawnie).
    Czy ktoś może mi powiedzieć jak wkradają się te 255 do mojej pętli?
    master
    
    unsigned char dana_spi[3]={4,4,4};
    unsigned char dana_i;
    interrupt [SPI_STC] void spi_isr(void)
    {       
    	SPCR=0b01111011;
    	dana_spi[dana_i]=SPDR;
    	dana_i++;
    	if(dana_i==3)
    	{
    		dana_i=0;
    	}
            else
            {
            	SPDR=dana_spi[dana_i];
            	SPCR=0b11111011;
            }
            
    }
    
    // Declare your global variables here
    void send_spi(void)
    {		
    	dana_i=0;
    	SPDR=dana_spi[dana_i];
    	SPCR=0b11111011;         
    } 


    slave
    
    unsigned char dana_spi[3]={1,2,3};
    unsigned char dana_i;
    interrupt [SPI_STC] void spi_isr(void)
    {       
    	dana_spi[dana_i]=SPDR;             
    	dana_i++;             
    	if(dana_i==3)
    		dana_i=0;
    	SPDR=dana_spi[dana_i]; 
    }


    Dodano po 5 [godziny] 3 [minuty]:

    Po całym dniu prób, rozwiązanie zagadki okazało się jak zwykle banalne, otóż pomimo wyłączonego układu SPI przy starcie MASTERA (załączenie zasilania) w jakiś cudowny sposób wywoływało to przerywanie od SPI (SPIE=0) i wpisywało całą tablice 255 (mimo deklaracji tablicy i wpisanej zawartości). Rozwiązaniem okazało się wstawienie pętli zwłoki czasowej tuż przed miejscem konfiguracji SPI. Mam nadziej że moje cało dniowe zmagania komuś się przydadzą, pozdrawiam.
REKLAMA