2014-06-11 100 views
0

每個人,我想寫我的字符串並存儲在spi eeprom中,然後從spi eeprom讀回,並通過uart在終端中顯示。我已經按照[1]中的步驟操作:http://ww1.microchip.com/downloads/en/DeviceDoc/21822E.pdf。但它似乎只能顯示一個字母。我不知道另一封信是否保存在spi eeprom中。我希望有一個人可以幫助我。Atmega8A uart spi eeprom

我正在使用: 芯片:Atmega8a 軟件:avr studio 5 終端:Bray終端。

#include <avr/io.h> 
    #include <util/delay.h> 

    void serial_init(void) 
    { 
     UBRRH = 0x00; 
     UBRRL = 95; 
     UCSRB = (1 << RXEN) | (1 << TXEN) | (1<<RXCIE); 
     UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)|(1 << UCSZ1); 
    } 
    void SPI_MasterInit(void) 
    { 
     DDRB = 0b00101100; 
     DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS); 
     SPCR = 0b01010000; 
     SPSR = 0b00000001; 
    } 
    char spi_transfer(volatile char data) 
    { 
     SPDR = data; 
     while(!(SPSR & (1<<SPIF))); 
     { 
     } 
     return SPDR; 
    } 
void SPI_MasterTransmit(unsigned long data) 
{ 
    unsigned long address; 
    DDR_SPI &= ~(1<<DD_SS); //ss goes low 
    spi_transfer(WREN); //enable write operation 
    DDR_SPI |= (1<<DD_SS); //ss goes high 

    _delay_ms(10); 

    DDR_SPI &= ~(1<<DD_SS); //ss goes low    
    spi_transfer(WRITE); // write data to memory         
    spi_transfer(address>>8);  // address MSB first 
    spi_transfer(address); 
    spi_transfer(data);   // send lsb 
    DDR_SPI |= (1<<DD_SS); //ss goes high 

}int resetEEPROM() 
{ 
    DDR_SPI &= ~(1<<DD_SS);    // Select EEPROM 
    spi_transfer(WREN); // Send WRITE_ENABLE command 
    DDR_SPI |= (1<<DD_SS);    // Release EEPROM 
    DDR_SPI &= ~(1<<DD_SS);     // Select EEPROM again after WREN cmd 
    spi_transfer(WRDI);  // send CHIP_ERASE command 
    DDR_SPI |= (1<<DD_SS);    // Release EEPROM 
    return 0; 
} // END eraseEEPROM() 

unsigned long SPI_MasterReceive(unsigned long address) //terima data //read address 
{ 
    unsigned long data; 
    DDR_SPI &= ~(1<<DD_SS); //ss goes low 
    spi_transfer(READ); //enable write operation 
    spi_transfer(address>>8);  // address MSB first 
    spi_transfer(address); 
    data = spi_transfer(0xff); 
    DDR_SPI |= (1<<DD_SS); //goes high 
    return data; 
} 
int main(void) 
{ 
     long int data; 
    unsigned long address; 
    serial_init(); 
    SPI_MasterInit(); 
    resetEEPROM(); 
    data = Usart_Receive(); 

    while (1) 
    { 
     if (Usart_Receive() == '.') 
      { 
      USART_Print("\r\nStore\r\n"); 
         SPI_MasterTransmit(data); //store in spi eeprom 
         } 
       if (Usart_Receive() == '>') 
     { 
      USART_Print("\nout \r\n"); 
      data = SPI_MasterReceive(address); //read data from the memory 
      Usart_Transmit(data); 
     } 

    }  
    return 0; 
} 

回答

0

有一種方法可以一次寫入多個字節的EEPROM,但您的代碼不會這樣做。相反,您每寫入操作寫入一個字節,並始終在同一地址。您將覆蓋任何以前的字節與每個新的字節。

如果要存儲多個字節,則需要在寫入時更改地址,或者一次更改多個字節的寫入方式。 (請注意,如果它們是EEPROM內存的同一頁,則只能寫入多個字節。)

+0

你能指點我的一些示例代碼的方向,讓我開始瞭解地址? 例如這是否與它有關: 'for(i = 0; i <100; i ++){}' 謝謝 – OooO

+0

我剛纔查看了您提供的數據表。你的代碼很好地保存了一個字節。您現在需要做的是決定如何管理EEPROM。也許是循環緩衝區?我不知道你的計劃。在任何情況下,您都需要跟蹤要寫入下一個位置的變量,以及您想要從中讀取的位置。當你寫時,增加地址變量。如果您希望在設備關閉時保持該值,那麼您甚至可以將該值保存在EEPROM本身中,可能在第一個地址。 – UncleO

+0

我無法在評論部分發布整個編碼,因此我將其發佈在答案部分。 – OooO

0

也許是循環緩衝區?

這是我的循環緩衝區代碼。在此基礎上http://www.rn-wissen.de/index.php/UART_mit_avr-gcc

#include <avr/io.h> 
    #include <fifo.h> 
    #define FIFOBUF_SIZE 128 
    uint8_t fifobuf[FIFOBUF_SIZE]; 
    fifo_t fifo; 


    ISR (USART_RXC_vect) 
    { 
     _inline_fifo_put(&fifo, UDR); 
    } 

    void serial_init(void) 
    { 
     cli(); 
     UBRRH = 0x00; 
     UBRRL = 95; 
     UCSRB = (1 << RXCIE) | (1 << RXEN) | (1 << TXEN); 
     UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); 
     sei(); 
    } 

    void fifo_init (fifo_t *f, uint8_t * buffer, const uint8_t size) 
    { 
     f-> count = 0; 
     f-> pread = f-> pwrite = buffer; 
     f-> read2end = f-> write2end = f-> size = size; 
    } 
    static inline int Usart_Transmit (const uint8_t c) 
    { 
     PORTD= 0b00000100; //RTS Enable 
     while ((UCSRA & (1 << UDRE)) ==0) {}; 
     UDR = c; 
     PORTD= 0b00000000; //RTS Enable 
     return 1; 
    } 


    int main(void) 
{ 
    unsigned long data; 
    unsigned long address; 
    fifo_init(&fifo, fifobuf, FIFOBUF_SIZE); 
    serial_init();  
    while (1) 
    { 
    SPI_MasterInit(); 
    resetEEPROM();  
    SPI_MasterTransmit(Usart_Receive()); 
    _delay_ms(100); 
    if (fifo.count > 0)   //; fifo.count >8 ; fifo.count 
     {  
     Usart_Transmit(_inline_fifo_get(&fifo)); 
     }  
    data = SPI_MasterReceive(address); //read data from the memory 
    _delay_ms(100); 
    Usart_Transmit(data);  
    }  
    return 0;  
} 

就出來了所有的信件,但不是按照順序。像這樣的例子" bfabeaabbfcabf ",我只是類型" abcdef "

你能告訴我如何在SPI EEPROM中設置EEPROM地址。像例如給我看一些關於這個SPI EEPROM地址的鏈接或例子。我請求你的善意幫助我解決這個問題,因爲我已經在互聯網上搜索了大約2個月的時間,只有幾個關於如何處理SPI EEPROM地址的例子。大部分我剛剛發現ATmega EEPROM,LTD。他們都不給我一個好的結果。預先感謝您的時間。 :)