Вот пример моего работающего кода как раз на меге 128 чип дб161. Если с железом проблем нет, должно работать. Работоспособность можно проверить чтением статусного регистра.
Код
void SPI_Init(void)
{
PORT_SPI |= (1<<SCK)|(1<<MOSI)|(1<<MISO)|(1<<CS_SPI_1);
DDR_SPI |= (1<<SCK)|(1<<MOSI)|(1<<CS_SPI_1);
DDR_SPI &= ~(1<<MISO);
SPSR = (1<<SPI2X);
SPCR = (1<<SPE)|(1<<MSTR); //Mode 0
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Записываем байт
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void SPI_Write_Byte(unsigned char b)
{
SPDR = b;
while ((SPSR & (1<<SPIF)) == 0);
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Читаем байт
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
unsigned char SPI_Read_Byte(void)
{
SPDR = 0x00;
while ((SPSR & (1<<SPIF)) == 0);
return SPDR;
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Чтение статусного регистра
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
unsigned char AT45_Read_Status(void)
{
unsigned char tmp;
AT45_ON;
SPI_Write_Byte(AT45_OP_STATUS_REGISTER_READ);
tmp = SPI_Read_Byte();
AT45_OFF;
return tmp;
}
unsigned char AT45_Check_Ready(void)
{
return (AT45_Read_Status() & (1<<AT45_STATUS_FLAG_BUSY));
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Чтение данных
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void AT45_Flash_Read(unsigned int page, unsigned int addr_on_page, unsigned int bcnt, unsigned char *buf)
{
unsigned int i;
AT45_ON;
SPI_Write_Byte(AT45_OP_CONTINUOUS_ARRAY_READ);
SPI_Write_Byte((unsigned char)(page>>6));
SPI_Write_Byte((unsigned char)(page<<2)|(unsigned char)(addr_on_page>>8));
SPI_Write_Byte((unsigned char)addr_on_page);
SPI_Write_Byte(0);
SPI_Write_Byte(0);
SPI_Write_Byte(0);
SPI_Write_Byte(0);
i = 0;
do
{
*(buf + i) = SPI_Read_Byte();
i++;
}while(i<bcnt);
AT45_OFF;
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Чтение данных из буфера
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void AT45_Buf_Read(unsigned char buf_num, unsigned int addr_on_page, unsigned int bcnt, unsigned char *buf)
{
unsigned int i;
AT45_ON;
switch(buf_num)
{
case BUFER_1:
SPI_Write_Byte(AT45_OP_BUFFER_1_READ);
break;
case BUFER_2:
SPI_Write_Byte(AT45_OP_BUFFER_2_READ);
break;
default:
return;
}
SPI_Write_Byte(0);
SPI_Write_Byte((unsigned char)(addr_on_page>>8));
SPI_Write_Byte((unsigned char)addr_on_page);
SPI_Write_Byte(0);
i = 0;
do
{
*(buf + i) = SPI_Read_Byte();
i++;
}while(i<bcnt);
AT45_OFF;
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Запись данных в буфер
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void AT45_Buf_Write(unsigned char buf_num, unsigned int addr_on_page, unsigned int bcnt, unsigned char *buf)
{
unsigned int i;
AT45_ON;
switch(buf_num)
{
case BUFER_1:
SPI_Write_Byte(AT45_OP_BUFFER_1_WRITE);
break;
case BUFER_2:
SPI_Write_Byte(AT45_OP_BUFFER_2_WRITE);
break;
default:
return;
}
SPI_Write_Byte(0);
SPI_Write_Byte((unsigned char)(addr_on_page>>8));
SPI_Write_Byte((unsigned char)addr_on_page);
i = 0;
do
{
SPI_Write_Byte(*(buf + i));
i++;
}while(i<bcnt);
AT45_OFF;
}
#define AT45_OP_BUFFER_1_WRITE 0x84
// запись буфера 2
#define AT45_OP_BUFFER_2_WRITE 0x87
// чтение буфера 1
#define AT45_OP_BUFFER_1_READ 0xD4
// чтение буфера 2
#define AT45_OP_BUFFER_2_READ 0xD6
// Буфер 1 в основную страницу памяти программы с встроенным стиранием
#define AT45_OP_B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83
// Буфер 2 в основную страницу памяти программы с встроенным стиранием
#define AT45_OP_B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86
// Буфер 1 в основную страницу памяти программы без встроенного стирания
#define AT45_OP_B1_TO_MM_PAGE_PROG_WITHOUT_ERASE 0x88
// Буфер 2 в основную страницу памяти программы без встроенного стирания
#define AT45_OP_B2_TO_MM_PAGE_PROG_WITHOUT_ERASE 0x89
// Основная страница памяти программы сквозь буфер 1
#define AT45_OP_MM_PAGE_PROG_THROUGH_B1 0x82
// Основная страница памяти программы сквозь буфер 2
#define AT45_OP_MM_PAGE_PROG_THROUGH_B2 0x85
// автоматическая перезапись страницы через буфер 1
#define AT45_OP_AUTO_PAGE_REWRITE_THROUGH_B1 0x58
// автоматическая перезапись страницы через буфер 2
#define AT45_OP_AUTO_PAGE_REWRITE_THROUGH_B2 0x59
// сравнение основной страницы памяти с буфером 1
#define AT45_OP_MM_PAGE_TO_B1_COMP 0x60
// сравнение основной страницы памяти с буфером 2
#define AT45_OP_MM_PAGE_TO_B2_COMP 0x61
// передача основной страницы памяти в буфер 1
#define AT45_OP_MM_PAGE_TO_B1 0x53
// передача основной страницы памяти в буфер 2
#define AT45_OP_MM_PAGE_TO_B2 0x55
// регистр состояния
#define AT45_OP_STATUS_REGISTER_READ 0xD7
// чтение основной страницы памяти
#define AT45_OP_MAIN_MEMORY_PAGE_READ 0xD2
// последовательно чтение
#define AT45_OP_CONTINUOUS_ARRAY_READ 0xE8
// очистка 528 байт страницы
#define AT45_OP_PAGE_ERASE 0x81
// очистка 512 страниц
#define AT45_OP_BLOCK_ERASE 0x50