ATMEGA8A + SPI memory strange behavior

I've bought SPI memory MX25L8006EPI and now I try to connect it to ATMEGA8A to test it. The schematic is very simple and doesn't change from others over the internet:

在这里输入图像描述

ATMEGA8A works at 8Mz internal oscillator, 3.3V. The fuses are HIGH: 0xD1, LOW: 0xE4.

I use Atmel Studio 7 for coding and AVRISP mkII to programming the uC. Since EEPROM needs 3.3V I've connected 5V 700mA power supply module using LM317 as you can see on the scheme. I don't think it matters but anyway ...

The code is also very simple, I've partly copied that from some page in the Internet:

#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("rnSet status:%drn",status);
    SetStatus(status);
    status = GetStatus();
    DEBUG_PRINT("rnGet status:%drn",status);
    byte buffer[3];
    Get_Identification(buffer);
    DEBUG_PRINT("Byte0:%xrn", buffer[0]);
    DEBUG_PRINT("Byte1:%xrn", buffer[1]);
    DEBUG_PRINT("Byte2:%xrn", buffer[2]);

    while (1) 
    {       
    }
}

DEBUG_PRINT is my function to send formatted string throught USART. I use it to print out debug info.

Everything looks fine but when I run that I get some strange behavior. The output is:

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

Firstly I set status register using WRSR opcode. it should set it to 00011100 but when I read the status using RDSR opcode I get 00011000.

Ok, maybe there is some trouble with status register. Then I try to read ID register using RDID opcode. It should return 3 bytes - 0xC2 0x20 0x14. But insted I get 0x80 0x0 0x10.

It would be understandable if I get no answer or all 0x00 or 0xFF. But here I read some answer, the problem that the response is totally wrong. Even more interesting is that if I connect the EEPROM to Arduino using at least the same code it works without problem.

I feel that the problem is quite small. It looks that maybe some data order wrong or transfer speed or something like that but I can't get it work.


根据此数据表,当BP2:0设置为5,6或7时,所有块都受到保护。也许,当将其设置为7时,内存仅将其设置为6,因为它没有区别。

链接地址: http://www.djcxy.com/p/78612.html

上一篇: 浮点和双变量的比较

下一篇: ATMEGA8A + SPI内存奇怪的行为