[英]Atmega8A uart spi eeprom
所有人,我想在spi eeprom中寫入並存儲我的字符串,然后從spi eeprom中讀取並通過uart在終端中顯示。 我已經按照[1]中的步驟進行了操作: http : //ww1.microchip.com/downloads/en/DeviceDoc/21822E.pdf 。 但似乎只能顯示一個字母。 我不知道另一封信是否保存在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;
}
有一種方法可以一次將多個字節寫入EEPROM,但是您的代碼不會這樣做。 取而代之的是,每個寫操作只寫一個字節,並且始終在同一地址。 您要用每個新的字節覆蓋以前的任何字節。
如果要存儲一個以上的字節,則需要在寫入時更改地址,或一次將寫入方式更改為一個以上的字節。 (請注意,如果它們是EEPROM存儲器的同一頁,則只能寫入多個字節。)
也許是循環緩沖區?
這是我的循環緩沖區代碼。 基於此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的信息。 而且他們都不是給我一個很好的結果。 在此先感謝您的寶貴時間。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.