0

everyone, I want to write and store my string at spi eeprom, then read back from spi eeprom and display in terminal through uart. I already follow the step in [1]: http://ww1.microchip.com/downloads/en/DeviceDoc/21822E.pdf . But it seem that it can only display one letter. I don't know if the other letter is save in spi eeprom or not. I hope someone can help me.

I am using: chip:Atmega8a software:avr studio 5 terminal: Bray terminal.

    #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;   
}
OooO
  • 13
  • 1
  • 8

2 Answers2

0

There is a way to write more than one byte to the EEPROM at once, but your code does not do that. Instead, you are writing one byte per write operation, and always at the same address. You are overwriting any previous bytes with each new one.

If you want to store more than one byte, you need to change the address as you write, or change the way you are writing to more than one byte at a time. (Note that you can only write multiple bytes if they are the same page of EEPROM memory.)

UncleO
  • 8,299
  • 21
  • 29
  • Would you be able to point me in the direction of some sample code to get me started about the address? e.g. Does this have to do with it: `for(i=0; i<100;i++){}` thank – OooO Jun 17 '14 at 06:15
  • I just looked at the datasheet you supplied. Your code follows it well for storing a single byte. What you need to do now is decide on how you are going to manage the EEPROM. Perhaps a circular buffer? I don't know your plans. In any case, you need to keep track in variables of where you want to write to next, and where you want to read from, too. When you write, increment the address variable. If you want that to persist when the device is off, then you can even keep that value in the EEPROM itself, perhaps at the first address. – UncleO Jun 17 '14 at 18:20
  • I cannot post the whole coding at the comment part, that why I post it in answer part. – OooO Jun 18 '14 at 10:49
0

Perhaps a circular buffer?

Here are my Circular Buffer code. Based on this 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;    
}

it Came out all of the letter, but not follow the sequence. Example like this " bfabeaabbfcabf ", I am only type " abcdef "

And can you show me how to set the EEPROM address in spi EEPROM. Like e.g. show me some link or example about this spi EEPROM address. I ask for your Kindness to help me about this because I have been about 2 months searching on the internet, there only few examples on how to handle spi EEPROM address. Mostly I just found about ATmega EEPROM, LTD. And all of Them are not give me a good result. Thank in advance for your time. :)

OooO
  • 13
  • 1
  • 8