2017-08-26 85 views
0

我買了SPI內存MX25L8006EPI,現在我試着將它連接到ATMEGA8A來測試它。原理很簡單,別人在互聯網上並沒有改變:ATMEGA8A + SPI內存奇怪行爲

enter image description here

ATMEGA8A工作在8Mz內部振盪器,3.3V。熔絲爲高電平:0xD1,低電平:0xE4。

我使用Atmel Studio 7編碼和AVRISP mkII來編程uC。 由於EEPROM需要3.3V電壓,因此我已經使用LM317連接了5V 700mA電源模塊,正如您在方案中看到的一樣。我不認爲它很重要,但無論如何...

的代碼也很簡單,我已經抄部分從某些網頁在互聯網上:

#define SLAVESELECT (PORTB &= ~(1<<PORTB2)) 
#define SLAVEDESELECT (PORTB |= (1<<PORTB2)) 

#define WREN 6 
#define WRDI 4 
#define RDSR 5 
#define WRSR 1 
#define READ 3 
#define WRITE 2 
#define RDID 0x9F 

#define byte unsigned char 

void SPI_Init() 
{ 
    DDRB = (1<<PORTB2)|(1<<PORTB3)|(1<<PORTB5); 
    SLAVEDESELECT; 
    //SPSR |= (1<<SPI2X); 
    SPCR |= (1<<SPE)|(1<<MSTR)|(1 << SPR1); 
    _delay_ms(10); 
} 

byte SPI_Transfer(volatile byte data) 
{ 
    SPDR = data; 
    while (!(SPSR & (1<<SPIF))); 
    return SPDR; 
} 

void Get_Identification(byte data[3]) 
{ 
    SLAVESELECT; 
    SPI_Transfer(RDID); 
    data[0] = SPI_Transfer(0xFF); 
    data[1] = SPI_Transfer(0xFF); 
    data[2] = SPI_Transfer(0xFF); 
    SLAVEDESELECT; 
} 

byte GetStatus() 
{ 
    byte status; 
    SLAVESELECT; 
    SPI_Transfer(RDSR); 
    status = SPI_Transfer(0xFF); 
    SLAVEDESELECT; 
    return status; 
} 

void SetWriteEnable(short ebable) 
{ 
    SLAVESELECT; 
    SPI_Transfer((ebable != 0) ? WREN : WRDI); 
    SLAVEDESELECT; 
} 

void SetStatus(byte status) 
{ 
    SetWriteEnable(1); 
    SLAVESELECT; 
    SPI_Transfer(WRSR); 
    SPI_Transfer(status); 
    SLAVEDESELECT; 
    _delay_ms(100); 
} 

int main(void) 
{ 
    SPI_Init(); 
    byte status = 0x1C; 
    DEBUG_PRINT("\r\nSet status:%d\r\n",status); 
    SetStatus(status); 
    status = GetStatus(); 
    DEBUG_PRINT("\r\nGet status:%d\r\n",status); 
    byte buffer[3]; 
    Get_Identification(buffer); 
    DEBUG_PRINT("Byte0:%x\r\n", buffer[0]); 
    DEBUG_PRINT("Byte1:%x\r\n", buffer[1]); 
    DEBUG_PRINT("Byte2:%x\r\n", buffer[2]); 

    while (1) 
    {  
    } 
} 

DEBUG_PRINT是我的函數來發送格式化字符串通過USART。我用它來打印出調試信息。

一切看起來不錯,但是當我運行時,我得到了一些奇怪的行爲。輸出是:

Set status:28 
Get status:24 
Byte0:80 
Byte1:0 
Byte2:10 

首先,我使用WRSR操作碼設置狀態寄存器。它應該將它設置爲00011100,但是當我使用RDSR操作碼讀取狀態時,我得到00011000.

好吧,也許狀態寄存器有一些問題。然後我嘗試使用RDID操作碼讀取ID寄存器。它應該返回3個字節​​ - 0xC2 0x20 0x14。但insted我得到0x80 0x0 0x10。

如果我沒有回答或全部爲0x00或0xFF,這將是可以理解的。但是在這裏我讀了一些答案,答案是完全錯誤的問題。更有趣的是,如果我使用至少相同的代碼將EEPROM連接到Arduino,它的工作沒有問題。

我覺得問題很小。它看起來也許是一些數據順序錯誤或傳輸速度或類似的東西,但我不能得到它的工作。

+0

SPI時鐘相位和極性設置是否符合EEPROM的要求? –

+1

是的,芯片工作在SPI模式0和3.目前CPOL = 0,CPHA = 0所以它在模式0,但我也試過模式3 - 結果相同。 – folibis

回答

0

根據此datasheet,當BP2:0設置爲5,6或7時,所有塊都受到保護。也許當您將其設置爲7時,內存僅將其設置爲6,因爲它不會使其設置爲6一個區別。

+0

感謝您的回覆,@UncleO!你是對的。內存可以通過將BP設置爲5,6或7來保護。但「BP2」是可寫的,應該進行設置。另外,如果我發送'11111111',然後讀取狀態,則返回相同的錯誤結果('00011000')。至少應該設置'SRWD'。如果我將芯片連接到'Arduino',狀態寄存器的所有位都可以正確設置 – folibis