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

Atmega32 , problem przy współpracy z zewnętrznym EEPROMEM po

super_sonic 10 Paź 2009 11:25 1133 7
REKLAMA
  • #1 7110583
    super_sonic
    Poziom 17  
    Witam
    Mam problem z SPI w Atmedze32. Staram się skomunikować ją z pamięcią 25LC128.

    SPI inicjalizuję następujaco
    
    void InicjalizacjaSPI(void)
    {
        // Wyjścia SS, SCK, oraz MOSI są wyjściami
        DDRB = _BV(SPI_SS) | _BV(SPI_MOSI) | _BV(SPI_SCK);
        // Ustawiamy SS oraz SCK w stan wysoki
        PORTB = _BV(SPI_SS) | _BV(SPI_SCK);
        // Uaktywniamy SPI, tryb Master, dzielnik 64
        SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
    }
    


    Bajt pod wskazany adres wysyłam następująco:
    
    void WyslijZnakEEPROM(char ch, short int adres)
    {    
        // Ustawiam linię SS w stan niski
        PORTB &= ~_BV(SPI_SS);
        // Instrukcja zapisu zgodnie z dokumentacją pamięci EEPROM
        SPDR = 0b00000010;
        while(!(SPSR & (1<<SPIF)));  
        // Pierwsza połowa adresu
        SPDR = (adres>>8);
        while(!(SPSR & (1<<SPIF)));
        // Druga połowa adresu  
        SPDR = adres;
        while(!(SPSR & (1<<SPIF)));
        // Znak do zapisu  
        SPDR = ch;
        while(!(SPSR & (1<<SPIF)));  
        // Ustawiam linię SS w stan wysoki
        PORTB |= _BV(SPI_SS);
    }
    


    Odczyt z pamięci odbywa się tak:
    
    char OdbierzZnakEEPROM(short int addr) 
    {
        // Ustawiam linię SS w stan niski 
        PORTB &= ~_BV(SPI_SS);
        // Instrukcja odczytu z pamięci
        SPDR = 0b00000011;
        while(!(SPSR & (1<<SPIF))); 
        // Pierwsza połowa adresu
        SPDR = (addr>>8);   
        while(!(SPSR & (1<<SPIF))); 
        // Druga połowa adresu
        SPDR = addr;   
        while(!(SPSR & (1<<SPIF))); 
        // Odczyt zmiennej
        addr=SPDR; 
        // Ustawiamy linię SS w stan wysoki
        PORTB |= _BV(SPI_SS);
        return addr; 
    } 
    


    Wyjście SS procesora podpięte jest pod wejście CS pamięci, linie MISO i MOSI odpowiednio do SO i SI, SCK do SCK. Wejścia HOLD oraz WP pamięci podpięte są do +Vcc. Atmega pracuje na zewnętrznym kwarcu 16MHz. Po próbie zapisu i odczytu dowolnego znaku pod dowolny adres w EEPROMIE, zwracany jest znak '?'. Nie mam pomysłu co może być problemem, może któryś z kolegów znajdzie błąd w moim rozumowaniu.
  • REKLAMA
  • #2 7110635
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #3 7110655
    super_sonic
    Poziom 17  
    Dziękuję za sugestię, już to sprawdzam.

    Procek do dokładnie: Atmega32 16AU

    Hmm podłączyłem wejście CS pamięci do PB2 procesora. SS Ustawiłem jako wyjście i ustawiłem w stan wysoki. Przed operacjami odczytu i zapisu ustawiam PB2 w stan niski a po operacji w stan wysoki. Efekt jest taki iż zamiast znaków zapytania otrzymuję puste znaki :-)

    W tej chwili kod wygląda następująco:
    
    #define SPI_MISO PB6
    #define SPI_MOSI PB5
    #define SPI_SS PB4
    #define SPI_SCK PB7
    #define SPI_CS PB2
    #define SPI_Disable() (PORTB |= _BV(SPI_CS));
    #define SPI_Enable() (PORTB &= ~_BV(SPI_CS));
    void InicjalizacjaSPI(void)
    {
    	DDRB = _BV(SPI_SS) | _BV(SPI_MOSI) | _BV(SPI_SCK) | _BV(SPI_CS);
    	PORTB = _BV(SPI_SS) | _BV(SPI_SCK) | _BV(SPI_CS);
    	SPCR = _BV(SPE) | _BV(MSTR);
    }
    
    char OdbierzZnakEEPROM(int addr) 
    { 
    	SPI_Enable();
    	SPDR = 0b00000011;
    	while(!(SPSR & (1<<SPIF))); 
    	SPDR = (addr>>8);   
      	while(!(SPSR & (1<<SPIF))); 
    	SPDR = (addr);   
      	while(!(SPSR & (1<<SPIF))); 
                 addr=SPDR; 
    	SPI_Disable();
                 return addr; 
    } 
    
    
    void WyslijZnakEEPROM(char ch, int adres)
    {
    	SPI_Enable();
    	SPDR = 0b00000010;
    	while(!(SPSR & (1<<SPIF))); 
    	SPDR = (adres>>8);
    	while(!(SPSR & (1<<SPIF))); 
    	SPDR = adres;
    	while(!(SPSR & (1<<SPIF)));  
    	SPDR = ch;
    	while(!(SPSR & (1<<SPIF)));  
    	SPI_Disable();
    }
    


    No już naprawdę nie wiem co jest nie tak :|
  • #4 7111174
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #5 7111448
    super_sonic
    Poziom 17  
    A czy Twoim zdaniem funkcje inicjalizacji SPI i zapisu znaku do EEPROMu są w porządku? wygląda na to, że odczyt już funkcjonuje, natomiast z zapisem jest gorzej
  • REKLAMA
  • Pomocny post
    #6 7111472
    Konto nie istnieje
    Poziom 1  
  • #7 7111598
    super_sonic
    Poziom 17  
    Czy pomiędzy operacjami odczytu, zapisu, czy wysyłania polecenia WREN są konieczne pauzy? A jeśli tak to jakie? :)

    Ok już wszystko działa jak należy. Dziękuję serdecznie koledze :)
  • #8 7111682
    Konto nie istnieje
    Poziom 1  
REKLAMA