Я купил память SPI MX25L8006EPI, и теперь я пытаюсь подключить его к ATMEGA8A для проверки. Схема очень проста и не отличается от других в Интернете:
ATMEGA8A работает на внутреннем генераторе 8 МГц, 3,3 В. Предохранители HIGH: 0xD1, LOW: 0xE4.
Я использую Atmel Studio 7 для кодирования и AVRISP mkII для программирования UC. Поскольку EEPROM требует 3,3 В, я подключил модуль питания 5 В 700 мА с помощью LM317, как вы можете видеть на схеме. Я не думаю, что это важно, но все же...
Код тоже очень простой, я его частично скопировал с какой-то странички в интернете:
#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
. Он должен вернуть 3 байта — 0xC2 0x20 0x14. Но вместо этого я получаю 0x80 0x0 0x10.
Было бы понятно, если бы я не получил ответа или все 0x00 или 0xFF. Но вот я прочитал какой-то ответ, проблема в том, что ответ совершенно неправильный. Еще более интересно то, что если я подключу EEPROM к Arduino, используя хотя бы тот же код, он будет работать без проблем.
Я чувствую, что проблема довольно мала. Похоже, что может быть какой-то неправильный порядок данных или скорость передачи или что-то в этом роде, но я не могу заставить это работать.