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

[mega2560][c] kłopot z SPI

majster256 23 Cze 2008 23:04 1842 16
  • #1 5278956
    majster256
    Poziom 21  
    witam mam problem z SPI

    ustawiam rejestr zgodnie z nota katalogową
    
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    


    ustawiam piny MOSI, SCK jako wyjście reszta jako wejście


    pozniej wysyłam dane
    /* Start transmission */
    SPDR = cData;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)));


    a na wyjściach nic sie nie dzieje :( sprawdzane miernikiem i oscyloskopem
    :cry: na poczatku z pinem SS nic nie robiłem (wisiał sobie) później podciągałem pod + i pod - ale to nic nie dało

    w rejestrze PRR0 mam same 0 ( rejestr oszczędzania energii)

    pomóżcie proszę:D
  • #2 5279188
    Korazon
    Poziom 12  
    W karcie katalogowej jest informacja, że SPI przełącza się automatycznie w tryb Slave, jeżeli SS jest ustawione jako wejście i wystąpi na nim poziom niski (co ma być wykryciem rozpoczęcia transmisji na magistrali przez inny układ Master). Więc podejrzewam, że konfiguracja SPI w trybie Master ma wyglądać następująco:
    #define SS (1 << 0)
    #define SCK (1 << 1)
    #define MOSI (1 << 2)
    #define MISO (1 << 3)
    #define SPIPORT PORTB
    #define SPIDDR DDRB
    
    SPIPORT |= SS; //SS w stan wysoki
    SPIDDR |= SS | SCK | MOSI; //SS, SCK, MOSI jako wyjścia
    SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); //konfiguracja SPI

    Poza tym blok SPI nie kontroluje pinu SS, więc jeśli jest tam dołączone wejście CS układu Slave, to trzeba go programowo wysterować, np:
    /* Start transmission */
    SPIPORT &= ~SS; //SS w stan niski
    SPDR = cData;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)));
    SPIPORT |= SS; //SS w stan wysoki
  • #3 5279217
    majster256
    Poziom 21  
    wejścia CS innych układów sa podłączone na innym porcie, ale nie w tym mój problem, mi po prostu sie nic nie pojawia na wyjściu :( ustawiłem ten SS jako wyjście i na nim stan wysoki. na wyjściach nadal nic
    nie ma jeszcze gdzieś jakiś rejestrów gdzie może być wyłączone SPI ?? bo kurcze grzebie grzebie i nic z tego :(
  • #4 5279686
    skywalker
    Poziom 22  
    Ja testowałem SPI na atmega16 i rzeczywiście jeśli SS jest wejsciem to
    powoduje to pewne problemy .
    Wystarczy podłączyć oscyloskop do układu i już transmisja znika.

    zrobiłem dla testu coś takiego(zapalanie i gaszenie diody led PD5 przy transmisji SPI ) :



    
    void SPI_MasterTransmit(char cData)
    {
     /* Start transmission */
     SPDR = cData;
     
     /* Wait for transmission complete */
     while(!(SPSR & (1<<SPIF)));
    
    }
    .
    .
    .
     int main(void )
    {
    .
    .
    .
     while(1)
      {
        SPI_MasterTransmit('A');
        PORTD ^= _BV(5);	
      }
    }
    


    przerobiłem ten przykład na własne potrzeby:
    http://winavr.scienceprog.com/avr-gcc-tutoria...al-interface-spi-of-avr-microcontrollers.html (jest tu mały błąd na początku powino być DDR_SPI = DDRB)
  • #5 5280797
    majster256
    Poziom 21  
    to niestety tez nic nie daje, a ISP działa normalnie wiec sprzętowo chyba to jest sprawne... ja już nie mam sił do tego :( nic się nie pojawia na wyjściach :(
  • #6 5280946
    skywalker
    Poziom 22  
    Witam
    Przyczyn może być wiele (zapewne to coś trywialnego )

    Podstawowa sprawa to schemat ... :

    1. czy układ prawidłowo się resetuje ?
    2. czy inne częsci programu działają (zakładam że tak).
    3. czy przerwania są włączone ?

    Mam nadzieję że test przeprowadzasz na takim bardzo krótkim kodzie gdzie jest tylko SPI i nic pozatym.

    mogę przesłać cały kod programu który u mnie działa
    może to coś z kompilatorem (błedne definicje adresów rejestrów ? )

    Mi wstawienie diody LED do układu sprawę debugowania ułatwiło :
    ( mogłem sprawdzić czy występuje fala prostokątna na anodzie )
  • #7 5280999
    Korazon
    Poziom 12  
    To może z kompilacją coś nie tak. A w makefile masz wybrany poprawny typ procesora? Tek przykłady które Ci podaliśmy teoretycznie powinny chodzić bez problemu :). Oprócz dodatkowego rejestru PRR0 nic innego nie wpływa na deaktywację SPI. Nie powiedziałeś, czy program Ci się zawiesza w momencie sprawdzania flagi SPIF czy idzie dalej. Może spróbuj tą instrukcję konfiguracyjną SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); dodać też w podprogramie wysyłania danych tuż przed instrukcją wpisania wartości do SPDR. Ostatecznie możesz spróbować zmusić do działania USART w trybie SPI, albo przeprowadzić transmisję programowo.
  • #8 5281250
    majster256
    Poziom 21  
    no w końcu ruszyło :) ustawione jako wyjścia i
    :D tylko jak odebrać coś z MCP3204 skoro on ma 4 bitową komendę a mój SPI wysyła 8, przez co nie można odebrać całości odpowiedzi z MCP, a odpowiedz jakaś jest bo widziałem na oscyloskopie:D
  • #9 5281335
    skywalker
    Poziom 22  
    Hmm Nota katalogowa MCP3204 strona 18...

    trzeba wysłać aż trzy bajty żeby odebrać 12bit wyniku.

    wg noty wysyłamy :

    1 bajt 000001DC
    2 bajt CCxxxxxx
    3 bajt xxxxxxxx

    D-tryb pracy (1bit), C konfiguracja (3bit), x -oznacza cokolwiek np same zera.
    Odbieramy drugi (4bity ) i trzeci bajt (całe 8bitów).
  • #10 5281439
    majster256
    Poziom 21  
    no wiec mam zrobic tak
    wysyłam 000001DC
    odbieram xxxxxxxx
    wysyłam CCxxxxxx
    odbieram xxxxxxxx
    wysyłam xxxxxxxx
    odbieram xxxxxxxx

    gdzie pierwszy odebrany bajt jest mi na nic?? a z pozostałych dwóch składam zmienna??

    odbieranie ogranicza się do czytania rejestru SPDR??

    nie będzie żadnego problemu z tym ze jest tylko 1 rejestr do wysyłania i odbierania danych?? w USART miałem dwa:)

    bo mi zawsze odbiera na obu bajtach 0xDF niezależnie od tego co jest na wejściu przetwornika:(
  • #12 5281613
    majster256
    Poziom 21  
    jak nie jak tak;p tzn nazwa jedna ale jak sie czyta to czyta inny i jak sie wpisuje to tez do innego :D

    a tak na serio to co z tym SPI :?:

    Dodano po 57 [sekundy]:

    w przypadku mojego mega2560 strona 227

    Dodano po 1 [godziny] 7 [minuty]:

    czy ja muszę w jakiś inny sposób skonfigurować te SPI?? no pomóżcie proszę :D
  • #13 5282845
    majster256
    Poziom 21  
    robię tak ze konfiguruje master, wysyłam dane, konfiguruje slave, odbieram dane, i tak 3 razy, ale jakoś nie odbieram tego co chce :( ale układ odpowiada :D teraz tylko odebrać to co wysyła.
  • Pomocny post
    #14 5282970
    skywalker
    Poziom 22  
    Witam

    Proszę spojrzeć na notę amtegi nic nie trzeba zmieniać wg producenta przetwornika AC :
    kostka pracuje w trybach 00 i 11 SPI tj wpisujesz albo 0x53 albo 0x5D
    tzn lepiej tak

    
    SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPOL)|(1<<CPHA);
    


    ps wg rysunkow z noty katalogowej rejest danych spi jest jednoczesnie wejsciem i wyjsciem tj wysyłając jednocześnie odbierasz.

    Skoro masz oscyloskop to przecież możesz sobie zapętlić wysyłanie odczytu i zobaczyć dokładnie to co odbierasz .
  • #15 5283094
    majster256
    Poziom 21  
    jesssss ruszyło:D dzięki ogromne
  • #16 5284663
    skywalker
    Poziom 22  
    Jeśli możesz Napisz w czym był problem ( np SPI nie działało ) to znacznie ułatwi innym pracę . (np gdyby ktoś przez przypadek również podłączał ten przetwornik to jakiegoś procesora Atmega )
  • #17 5330917
    majster256
    Poziom 21  
    zamieszczam kod ktory u mnie działa

    oczywiście wcześniej trzeba aktywować układ sygnałem na CS

    CH to numer kanału

    
    uint16_t wartoscADC ;
    uint8_t CH;
    
    //konfigurujemy SPI	
    DDR_SPI = (PIN_SS | PIN_SCK | PIN_MOSI);
    PORT_SPI = (PIN_SS | PIN_SCK | PIN_MOSI);
    	
    	
    SPCR = (1<<SPE)|(1<<MSTR)|(3<<SPR0)|(1<<CPOL)|(1<<CPHA);
    
    
    	//wysyłamy	
    	if(CH < 5)
    	{
    		SPDR = 0X06;
    	}else
    	{
    		SPDR = 0X07;
    	}
    
    	while(!(SPSR & (1<<SPIF)));
    	
    	SPDR = CH << 6;
    	while(!(SPSR & (1<<SPIF)));
    	
    
    	wartoscADC  = (SPDR << 12);
    
    	SPDR = 0;
    	while(!(SPSR & (1<<SPIF)));
    	
    
    	wartoscADC |= SPDR << 4;
    


    życzę owocnego programowania wszystkim którzy maja z tym problem:)
REKLAMA