求助:ATmega8对AT45DB161D访问的源代码的问题。
void Init_SPI(void){
DDRB|=(1<<DDB2)|(1<<DDB3)|(1<<DDB5);
PORTB &=~(1<<DDB5);
PORTB |= (1<<PORTB2);///SS=1
SPCR=(1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<CPOL); //Enable SPI in Master mode, mode 3, Fosc/2;//使能SPI,SPI选择为主机
SPSR=1;//SPI倍速,频率为外部时钟的一半(7.3728M/2)
}
void Write_SPI(unsigned char data)
{
SPSR &= ~(1<<SPIF);
SPDR = data;
while (!(SPSR & 0x80));
}
//格式化主存储器(以扇区<0A,0B,1……15>为单位删除所有页数据)
//Flash_Num--选择决定选择哪一片FLASH
void DF_format(unsigned char Flash_Num)
{
unsigned char i;
DF_SPI_ON;
DF_wait_busy(Flash_Num);
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
Write_SPI(SECTOR_ERASE);//7ch
Write_SPI(0x00);
Write_SPI(0x00);
Write_SPI(0x00);
DF_wait_busy(Flash_Num);
Write_SPI(SECTOR_ERASE);
Write_SPI(0x00);
Write_SPI(0x20);
Write_SPI(0x00);
for (i=1;i<16;i++)
{
DF_wait_busy(Flash_Num);
Write_SPI(SECTOR_ERASE);
Write_SPI(i << 2);
Write_SPI(0x00);
Write_SPI(0x00);
}
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
}
//擦除指定的主存储器页(地址范围0-4095)
//Flash_Num--选择决定选择哪一片FLASH
void DF_page_earse(unsigned int page,unsigned char Flash_Num)
{
DF_SPI_ON;
DF_wait_busy(Flash_Num);
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
Write_SPI(PAGE_ERASE);//81h
Write_SPI((unsigned char)(page >> 6));
Write_SPI((unsigned char)(page << 2));
Write_SPI(0x00);
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
}
//将保存在数组DF_buffer[]中的一页数据写入第二缓冲区后送入主存储区
//(先擦除后写入模式,页地址范围0-4095)
//Flash_Num--选择决定选择哪一片FLASH
void DF_write_page(unsigned int page,unsigned char Flash_Num)
{
unsigned int i;
DF_SPI_ON;
DF_wait_busy(Flash_Num);
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
Write_SPI(BUFFER_2_WRITE); //87h
Write_SPI(0x00);
Write_SPI(0x00);
Write_SPI(0x00);
for (i=0;i<Buffer_Length;i++)
{
Write_SPI(DF_buffer);
}
//DF_DESELECT_1;
if (page<4096)
{
//DF_SELECT_1;
DF_wait_busy(Flash_Num);
Write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);//86h
Write_SPI((unsigned char)(page>>6));
Write_SPI((unsigned char)(page<<2));
Write_SPI(0x00);
//DF_DESELECT_1;
}
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
}
//将指定主存储器页的数据转入第一缓冲区后读出,保存在DF_buffer[]数组中
//(页地址范围0-4095)
//Flash_Num--选择决定选择哪一片FLASH
void DF_read_page(unsigned int page,unsigned char Flash_Num)
{
unsigned int i;
DF_SPI_ON;
//while(!(DF_STA_PORT & (1<< DF_STATE)));
DF_wait_busy(Flash_Num);
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
Write_SPI(MM_PAGE_TO_B1_XFER);//53h
Write_SPI((unsigned char)(page >> 6));
Write_SPI((unsigned char)(page << 2));
Write_SPI(0x00);
//DF_DESELECT_1;
DF_wait_busy(Flash_Num);
//DF_SELECT_1;
Write_SPI(BUFFER_1_READ); //d4h
Write_SPI(0x00);
Write_SPI(0x00);
Write_SPI(0x00);
Write_SPI(0x00);
for (i=0;i<Buffer_Length;i++)
{
Write_SPI(0xFF);
DF_buffer = SPDR;
}
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
}
//以直接读取方式读取指定的主存储器页数据(页地址范围0-4095)
//Flash_Num--选择决定选择哪一片FLASH
void DF_MM_read_page(unsigned int page,unsigned char Flash_Num)
{
unsigned int i;
DF_SPI_ON;
//while(!(DF_STA_PORT & (1<< DF_STATE)));
DF_wait_busy(Flash_Num);
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
Write_SPI(MAIN_MEMORY_PAGE_READ);//d2h
Write_SPI((unsigned char)(page >> 6));
Write_SPI((unsigned char)(page << 2));
Write_SPI(0x00);
Write_SPI(0x00);
Write_SPI(0x00);
Write_SPI(0x00);
Write_SPI(0x00);
for (i=0;i<Buffer_Length;i++)
{
Write_SPI(0xff);
DF_buffer = SPDR;
}
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
}
//读取状态寄存器
// bit7 bit6 bit6 bit6 bit6 bit6 bit6 bit6
//RDY/BUSY COMP 1 0 1 1 PROTECT PAGE SIZE
//Flash_Num--选择决定选择哪一片FLASH
unsigned char DF_read_reg(unsigned char Flash_Num)
{
unsigned char temp;
DF_SPI_ON;
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
Write_SPI(READ_STATE_REGISTER);//d7h
Write_SPI(0xff);
temp=SPDR;
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
return temp;
}
//检查状态寄存器最高位是否为忙,并等待空闲
//Flash_Num--选择决定选择哪一片FLASH
void DF_wait_busy(unsigned char Flash_Num)
{
unsigned char state_reg=0x00;
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
Write_SPI(READ_STATE_REGISTER);//d7h
Write_SPI(0xff);
state_reg = SPDR ;
while((state_reg&0x80) == 0)
{
Write_SPI(0xff);
state_reg = SPDR ;
}
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
}
//将指定主存储器页的数据转入指定缓冲区
//Flash_Num--选择决定选择哪一片FLASH
void DF_mm_to_buf(unsigned char buffer,unsigned int page,unsigned char Flash_Num)
{
DF_SPI_ON;
DF_wait_busy(Flash_Num);
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
if (buffer==1)
Write_SPI(MM_PAGE_TO_B1_XFER);//53h
else
Write_SPI(MM_PAGE_TO_B2_XFER);//55h
Write_SPI((unsigned char)(page >> 6));
Write_SPI((unsigned char)(page << 2));
Write_SPI(0x00);
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
}
//读取指定缓冲区指定单元的数据,保存在DF_buffer[]数组中
//Flash_Num--选择决定选择哪一片FLASH
unsigned char DF_read_buf(unsigned char buffer,unsigned int start_address,
unsigned int length,unsigned char Flash_Num)
{
unsigned int i;
if (((Buffer_Length-1)-start_address)>=length)
{
DF_SPI_ON;
DF_wait_busy(Flash_Num);
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
if (buffer==1)
Write_SPI(BUFFER_1_READ); //d4h
else
Write_SPI(BUFFER_2_READ);
Write_SPI(0x00);
Write_SPI((unsigned char)(start_address >> 8));
Write_SPI((unsigned char)start_address);
Write_SPI(0x00);
for (i=0;i<length;i++)
{
Write_SPI(0xFF);
DF_buffer = SPDR;
}
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
return 1;
}
else
return 0;
}
//将DF_buffer[]数组中指定长度的数据写入指定缓冲区
//Flash_Num--选择决定选择哪一片FLASH
unsigned char DF_write_buf(unsigned char buffer,unsigned int start_address,
unsigned int length,unsigned char Flash_Num)
{
unsigned int i;
if(((Buffer_Length-1)-start_address)>=length)
{
DF_SPI_ON;
DF_wait_busy(Flash_Num);
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
if (buffer==1)
Write_SPI(BUFFER_1_WRITE);
else
Write_SPI(BUFFER_2_WRITE);
Write_SPI(0x00);
Write_SPI((unsigned char)(start_address >> 8));
Write_SPI((unsigned char)start_address);
for (i=0;i<length;i++)
{
Write_SPI(DF_buffer);
}
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
return 1;
}
else
{
DF_SPI_OFF;
return 0;
}
}
//将指定缓冲区中的数据写入主存储区的指定页(擦除模式)
//Flash_Num--选择决定选择哪一片FLASH
void DF_buf_to_mm(unsigned char buffer,unsigned int page,unsigned char Flash_Num)
{
DF_SPI_ON;
DF_wait_busy(Flash_Num);
if (page<4096)
{
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
if (buffer==1)
Write_SPI(B1_TO_MM_PAGE_PROG_WITH_ERASE);
else
Write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);
Write_SPI((unsigned char)(page>>6));
Write_SPI((unsigned char)(page<<2));
Write_SPI(0x00);
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
}
DF_SPI_OFF;
}
//将指定缓冲区中的数据写入主存储区的指定页(没有擦除)
//Flash_Num--选择决定选择哪一片FLASH
void DF_buf_to_mm_Without_Erase(unsigned char buffer,unsigned int page,unsigned char Flash_Num)
{
DF_SPI_ON;
DF_wait_busy(Flash_Num);
if (page<4096)
{
//DF_SELECT_1;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
if (buffer==1)
Write_SPI(B1_TO_MM_PAGE_PROG);
else
Write_SPI(B2_TO_MM_PAGE_PROG);
Write_SPI((unsigned char)(page>>6));
Write_SPI((unsigned char)(page<<2));
Write_SPI(0x00);
//DF_DESELECT_1;
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
}
DF_SPI_OFF;
}
//比较缓冲器1和DF_buffer数组的大小,
//如果相等,返回1,否则返回0;
//Flash_Num--选择决定选择哪一片FLASH
unsigned char Compare_Tow_Buffer(unsigned char Flash_Num)
{
unsigned char Mid_Reg_CMP = 0;
unsigned int Buffer_Address = 0;
DF_SPI_ON;
switch(Flash_Num)
{
case 1:DF_SELECT_1;break;
case 2:DF_SELECT_2;break;
case 3:DF_SELECT_3;break;
case 4:DF_SELECT_4;break;
default:break;
}
for(Buffer_Address=0; Buffer_Address<528; Buffer_Address++)
{
DF_wait_busy(Flash_Num);
Write_SPI(BUFFER_1_READ); // 0xD4 // 读取第一缓冲区
Write_SPI(0x00);
Write_SPI((unsigned char)(Buffer_Address>>8));
Write_SPI((unsigned char) (Buffer_Address<<2));
Write_SPI(0x00);
Write_SPI(0xff);
Mid_Reg_CMP = SPDR;
if(Mid_Reg_CMP != DF_buffer)
{
return 0;
}
}
switch(Flash_Num)
{
case 1:DF_DESELECT_1;break;
case 2:DF_DESELECT_2;break;
case 3:DF_DESELECT_3;break;
case 4:DF_DESELECT_4;break;
default:break;
}
DF_SPI_OFF;
return 1;
} 请高手帮忙看看,这些源代码问题出在哪里,我调试了好几天没有调好。谢谢 你先一点一点来吧。
先写一个字节到AT45DB161中,再读出来看看是否写对了。 不对哦 读状态是对的,其它都不对。 参考一下http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=919414&bbs_page_no=1&bbs_id=1000 4.1测试at45DB161D
#ifndef AT45DB161D_H
#define AT45DB161D_H
#include<global.h>
#include<iom128v.h>
#include<macros.h>
#include "at45db161d_commands.h"
#ifndef SPI
#define DATAOUT 11
#define DATAIN 12
#define SPICLOCK 13
#define SLAVESELECT 10
#define RESET 8
#define WP 7
/*
#define DF_CS_inactive digitalWrite(SLAVESELECT,HIGH)
#define DF_CS_active digitalWrite(SLAVESELECT,LOW)
*/
/*
#define DF_CS_inactive PORTB|=_BV(DDB0)
#define DF_CS_active PORTB&=~_BV(DDB0)
*/
#define DF_CS_inactive PORTB|=1
#define DF_CS_active PORTB&=0xfe
#endif /* SPI */
#define READY_BUSY 0x80
#define COMPARE 0x40
#define PROTECT 0x02
#define PAGE_SIZE 0x01
#define DEVICE_DENSITY 0x2C
struct ATD45DB161D_ID
{
uint8_t manufacturer;
uint8_t device;
uint8_t extendedInfoLength;
};
void ATD45DB161D_Init(void);
uint8_t ReadStatusRegister(void);
void ReadManufacturerAndDeviceID(struct ATD45DB161D_ID *id);
void ReadMainMemoryPage(uint16_t page, uint16_t offset);
void ContinuousArrayRead(uint16_t page, uint16_t offset, uint8_t low);
voidBufferRead(uint8_t bufferNum, uint16_t offset, uint8_t low);
voidBufferWrite(uint8_t bufferNum, uint16_t offset);
voidBufferToPage(uint8_t bufferNum, uint16_t page, uint8_t erase);
voidPageToBuffer(uint16_t page, uint8_t bufferNum);
voidPageErase(uint16_t page);
voidBlockErase(uint16_t block);
voidSectoreErase(uint8_t sector);
voidChipErase(void);
voidBeginPageWriteThroughBuffer(uint16_t page, uint16_t offset, uint8_t bufferNum);
voidEndAndWait(void);
int8_tComparePageToBuffer(uint16_t page, uint8_t bufferNum);
voidDeepPowerDown(void);
voidResumeFromDeepPowerDown(void);
#endif /* AT45DB161D_H */
#ifndef AT45DB161D_COMMANDS_H
#define AT45DB161D_COMMANDS_H
#define AT45DB161D_PAGE_READ 0xD2
#define AT45DB161D_CONTINUOUS_READ_LOW_FREQ 0x03
#define AT45DB161D_CONTINUOUS_READ_HIGH_FREQ 0x0B
#define AT45DB161D_BUFFER_1_READ_LOW_FREQ 0xD1
#define AT45DB161D_BUFFER_2_READ_LOW_FREQ 0xD3
#define AT45DB161D_BUFFER_1_READ 0xD4
#define AT45DB161D_BUFFER_2_READ 0xD6
#define AT45DB161D_BUFFER_1_WRITE 0x84
#define AT45DB161D_BUFFER_2_WRITE 0x87
#define AT45DB161D_BUFFER_1_TO_PAGE_WITH_ERASE 0x83
#define AT45DB161D_BUFFER_2_TO_PAGE_WITH_ERASE 0x86
#define AT45DB161D_BUFFER_1_TO_PAGE_WITHOUT_ERASE 0x88
#define AT45DB161D_BUFFER_2_TO_PAGE_WITHOUT_ERASE 0x89
#define AT45DB161D_PAGE_ERASE 0x81
#define AT45DB161D_BLOCK_ERASE 0x50
#define AT45DB161D_SECTOR_ERASE 0x7C
#define AT45DB161D_CHIP_ERASE_0 0xC7
#define AT45DB161D_CHIP_ERASE_1 0x94
#define AT45DB161D_CHIP_ERASE_2 0x80
#define AT45DB161D_CHIP_ERASE_3 0x9A
#define AT45DB161D_PAGE_THROUGH_BUFFER_1 0x82
#define AT45DB161D_PAGE_THROUGH_BUFFER_2 0x85
#ifdef AT45DB161D_EXPERT_MODE
/* Use the following commands at your own risk ! */
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_0 0x3D
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_1 0x2A
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_2 0x7F
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_3 0xA9
#define AT45DB161D_DISABLE_SECTOR_PROTECTION_0 0x3D
#define AT45DB161D_DISABLE_SECTOR_PROTECTION_1 0x2A
#define AT45DB161D_DISABLE_SECTOR_PROTECTION_2 0x7F
#define AT45DB161D_DISABLE_SECTOR_PROTECTION_3 0x9A
#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0x3D
#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0x2A
#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0x7F
#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0xCF
#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_0 0x3D
#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_1 0x2A
#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_2 0x7F
#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_3 0xFC
#define AT45DB161D_SECTOR_LOCKDOWN_0 0X3D
#define AT45DB161D_SECTOR_LOCKDOWN_1 0x2A
#define AT45DB161D_SECTOR_LOCKDOWN_2 0x7F
#define AT45DB161D_SECTOR_LOCKDOWN_3 0x30
#define AT45DB161D_PROGRAM_SECURITY_REGISTER_0 0x9B
#define AT45DB161D_PROGRAM_SECURITY_REGISTER_1 0x00
#define AT45DB161D_PROGRAM_SECURITY_REGISTER_2 0x00
#define AT45DB161D_PROGRAM_SECURITY_REGISTER_3 0x00
#endif /* AT45DB161D_EXPERT_MODE */
#define AT45DB161D_READ_SECTOR_PROTECTION_REGISTER 0x32
#define AT45DB161D_READ_SECTOR_LOCKDOWN_REGISTER 35H
#define AT45DB161D_READ_SECURITY_REGISTER 0x77
#define AT45DB161D_TRANSFER_PAGE_TO_BUFFER_1 0x53
#define AT45DB161D_TRANSFER_PAGE_TO_BUFFER_2 0x55
#define AT45DB161D_COMPARE_PAGE_TO_BUFFER_1 0x60
#define AT45DB161D_COMPARE_PAGE_TO_BUFFER_2 0x61
#define AT45DB161D_AUTO_PAGE_REWRITE_THROUGH_BUFFER_1 0x58
#define AT45DB161D_AUTO_PAGE_REWRITE_THROUGH_BUFFER_2 0x59
#define AT45DB161D_DEEP_POWER_DOWN 0xB9
#define AT45DB161D_RESUME_FROM_DEEP_POWER_DOWN 0xAB
#define AT45DB161D_STATUS_REGISTER_READ 0xD7
#define AT45DB161D_READ_MANUFACTURER_AND_DEVICE_ID 0x9F
#define AT45DB161D_BUFFER_1_READ_LEGACY 0X54
#define AT45DB161D_BUFFER_2_READ_LEGACY 0x56
#define AT45DB161D_PAGE_READ_LEGACY 0x52
#define AT45DB161D_CONTINUOUS_READ_LEGACY 0x68
#define AT45DB161D_STATUS_REGISTER_READ_LEGACY 0x57
#endif /* AT45DB161D_COMMANDS_H */
at45db161d.c原程序
#include "at45db161d.h"
#include<iom128v.h>
#include<macros.h>
#include<delay.h>
//#define DF_CS_inactive PORTB|=1
//#define DF_CS_active PORTB&=0xfe
uint8_t spi_transfer(uint8_t data)
{
SPDR = data;
while(!(SPSR & (1 << SPIF))) ;
return SPDR;
}
void ATD45DB161D_Init(void)
{
uint8_t clr;
/* Initialize pinout */
/*pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK, OUTPUT);
pinMode(SLAVESELECT, OUTPUT);
pinMode(DATAIN, INPUT);
*/
//DDRB|=(1<<DDB2)|(1<<DDB1)|(1<<DDB0);
//设置SS,SCK,MOSI为输出,MIOS为输入
DDRB&=0XF7;
DDRB|=0X07;
/* Disable device */
DF_CS_inactive;
/* Setup SPI 主机模式空闲时为高,采样结束沿采样 1/4主频率*/
SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA);
/* Cleanup registers */
clr = SPSR;
clr = SPDR;
}
uint8_tReadStatusRegister(void)
{
uint8_t status;
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send status read command */
spi_transfer(AT45DB161D_STATUS_REGISTER_READ);
/* Get result with a dummy write */
status = spi_transfer(0x00);
return status;
}
voidReadManufacturerAndDeviceID(struct ATD45DB161D_ID *id)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send status read command */
spi_transfer(AT45DB161D_READ_MANUFACTURER_AND_DEVICE_ID);
/* Manufacturer ID */
id->manufacturer = spi_transfer(0xff);
/* Device ID (part 1) */
id->device = spi_transfer(0xff);
/* Device ID (part 2) */
id->device = spi_transfer(0xff);
/* Extended Device Information String Length */
id->extendedInfoLength = spi_transfer(0xff);
}
voidReadMainMemoryPage(uint16_t page, uint16_t offset)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer(AT45DB161D_PAGE_READ);
/* Address (page | offset)*/
spi_transfer((uint8_t)(page >> 6));
spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
spi_transfer((uint8_t)(offset & 0xff));
/* 4 "don't care" bytes */
spi_transfer(0x00);
spi_transfer(0x00);
spi_transfer(0x00);
spi_transfer(0x00);
}
voidContinuousArrayRead(uint16_t page, uint16_t offset, uint8_t low)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer( low ? AT45DB161D_CONTINUOUS_READ_LOW_FREQ :
AT45DB161D_CONTINUOUS_READ_HIGH_FREQ );
/* Address (page | offset)*/
spi_transfer((uint8_t)(page >> 6));
spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
spi_transfer((uint8_t)(offset & 0xff));
}
voidBufferRead(uint8_t bufferNum, uint16_t offset, uint8_t low)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
if(bufferNum == 1)
{
spi_transfer(low ? AT45DB161D_BUFFER_1_READ_LOW_FREQ :
AT45DB161D_BUFFER_1_READ);
}
else
{
spi_transfer(low ? AT45DB161D_BUFFER_2_READ_LOW_FREQ :
AT45DB161D_BUFFER_2_READ);
}
/* 14 "Don't care" bits */
spi_transfer(0x00);
/* Rest of the "don't care" bits + bits 8,9 of the offset */
spi_transfer((uint8_t)(offset >> 8));
/* bits 7-0 of the offset */
spi_transfer((uint8_t)(offset & 0xff));
}
voidBufferWrite(uint8_t bufferNum, uint16_t offset)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_WRITE :
AT45DB161D_BUFFER_2_WRITE);
/* 14 "Don't care" bits */
spi_transfer(0x00);
/* Rest of the "don't care" bits + bits 8,9 of the offset */
spi_transfer((uint8_t)(offset >> 8));
/* bits 7-0 of the offset */
spi_transfer((uint8_t)(offset & 0xff));
}
voidBufferToPage(uint8_t bufferNum, uint16_t page, uint8_t erase)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Opcode */
if(erase)
{
spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_TO_PAGE_WITH_ERASE :
AT45DB161D_BUFFER_2_TO_PAGE_WITH_ERASE);
}
else
{
spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_TO_PAGE_WITHOUT_ERASE :
AT45DB161D_BUFFER_2_TO_PAGE_WITHOUT_ERASE);
}
/*
* 3 address bytes consist of :
* - 2 don’t care bits
* - 12 page address bits (PA11 - PA0) that specify the page in
* the main memory to be written
* - 10 don’t care bits
*/
spi_transfer((uint8_t)(page >> 6));
spi_transfer((uint8_t)(page << 2));
spi_transfer(0x00);
DF_CS_inactive;/* Start transfer */
DF_CS_active; /* If erase was set, the page will first be erased */
/* Wait for the end of the transfer */
while(!(ReadStatusRegister() & READY_BUSY))
{}
}
voidPageToBuffer(uint16_t page, uint8_t bufferNum)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer((bufferNum == 1) ? AT45DB161D_TRANSFER_PAGE_TO_BUFFER_1 :
AT45DB161D_TRANSFER_PAGE_TO_BUFFER_2);
/*
* 3 address bytes consist of :
* - 2 don’t care bits
* - 12 page address bits (PA11 - PA0) that specify the page in
* the main memory to be written
* - 10 don’t care bits
*/
spi_transfer((uint8_t)(page >> 6));
spi_transfer((uint8_t)(page << 2));
spi_transfer(0x00);
DF_CS_inactive;/* Start page transfer */
DF_CS_active;
/* Wait for the end of the transfer */
while(!(ReadStatusRegister() & READY_BUSY))
{}
}
voidPageErase(uint16_t page)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer(AT45DB161D_PAGE_ERASE);
/*
* 3 address bytes consist of :
* - 2 don’t care bits
* - 12 page address bits (PA11 - PA0) that specify the page in
* the main memory to be written
* - 10 don’t care bits
*/
spi_transfer((uint8_t)(page >> 6));
spi_transfer((uint8_t)(page << 2));
spi_transfer(0x00);
DF_CS_inactive;/* Start block erase */
DF_CS_active;
/* Wait for the end of the block erase operation */
while(!(ReadStatusRegister() & READY_BUSY))
{}
}
voidBlockErase(uint16_t block)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer(AT45DB161D_BLOCK_ERASE);
/*
* 3 address bytes consist of :
* - 2 don’t care bits
* - 9 block address bits (PA11 - PA3)
* - 13 don’t care bits
*/
spi_transfer((uint8_t)(block >> 3));
spi_transfer((uint8_t)(block << 5));
spi_transfer(0x00);
DF_CS_inactive;/* Start block erase */
DF_CS_active;
/* Wait for the end of the block erase operation */
while(!(ReadStatusRegister() & READY_BUSY))
{}
}
voidSectoreErase(uint8_t sector)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer(AT45DB161D_SECTOR_ERASE);
/*
* 3 address bytes consist of :
*/
if((sector == 0x0a) || (sector == 0x0b))
{
/*
*- 11 don’t care bits
*-
*- 12 don’t care bits
*/
spi_transfer(0x00);
spi_transfer(((sector & 0x01) << 4));
spi_transfer(0x00);
}
else
{
/*
*- 2 don't care bits
*- 4 sector number bits
*- 18 don't care bits
*/
spi_transfer(sector << 1);
spi_transfer(0x00);
spi_transfer(0x00);
}
DF_CS_inactive;/* Start block erase */
DF_CS_active;
/* Wait for the end of the block erase operation */
while(!(ReadStatusRegister() & READY_BUSY))
{}
}
voidChipErase(void)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send chip erase sequence */
spi_transfer(AT45DB161D_CHIP_ERASE_0);
spi_transfer(AT45DB161D_CHIP_ERASE_1);
spi_transfer(AT45DB161D_CHIP_ERASE_2);
spi_transfer(AT45DB161D_CHIP_ERASE_3);
DF_CS_inactive;/* Start chip erase */
DF_CS_active;
/* Wait for the end of the chip erase operation */
while(!(ReadStatusRegister() & READY_BUSY))
{}
}
voidBeginPageWriteThroughBuffer(uint16_t page, uint16_t offset, uint8_t bufferNum)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer((bufferNum == 1) ? AT45DB161D_PAGE_THROUGH_BUFFER_1 :
AT45DB161D_PAGE_THROUGH_BUFFER_2);
/* Address */
spi_transfer((uint8_t)(page >> 6));
spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
spi_transfer((uint8_t)offset);
}
voidEndAndWait(void)
{
DF_CS_inactive;/* End current operation */
DF_CS_active; /* Some internal operation may occur
* (buffer to page transfer, page erase, etc... ) */
/* Wait for the chip to be ready */
while(!(ReadStatusRegister() & READY_BUSY))
{}
}
int8_tComparePageToBuffer(uint16_t page, uint8_t bufferNum)
{
uint8_t status;
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer((bufferNum == 1) ? AT45DB161D_COMPARE_PAGE_TO_BUFFER_1 :
AT45DB161D_COMPARE_PAGE_TO_BUFFER_2);
/* Page address */
spi_transfer((uint8_t)(page >> 6));
spi_transfer((uint8_t)(page << 2));
spi_transfer(0x00);
DF_CS_inactive;/* Start comparaison */
DF_CS_active;
/* Wait for the end of the comparaison and get the result */
while(!((status = ReadStatusRegister()) & READY_BUSY))
{}
return ((status & COMPARE) == COMPARE);
}
voidDeepPowerDown(void)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer(AT45DB161D_DEEP_POWER_DOWN);
/* Enter Deep Power-Down mode */
DF_CS_inactive;
/* Safety delay */
delay_ms(100);
}
voidResumeFromDeepPowerDown(void)
{
DF_CS_inactive; /* Make sure to toggle CS signal in order */
DF_CS_active; /* to reset Dataflash command decoder */
/* Send opcode */
spi_transfer(AT45DB161D_RESUME_FROM_DEEP_POWER_DOWN);
/* Resume device */
DF_CS_inactive;
/* The CS pin must stay high during t_RDPD microseconds before the device
* can receive any commands.
* On the at45db161D t_RDPD = 35 microseconds. But we will wait 100
* (just to be sure). */
delay_ms(100);
}
测试程序1
voidATD45DB161D_test(void)
{
struct ATD45DB161D_ID *id1;
sendstring1("now test ATD45DB161D dataflash !\n");
sendstring1("1.ReadStatusRegister\n");
// sendchar1(char2hex(ReadStatusRegister()));
sendinthex1(ReadStatusRegister());
sendstring1("\n");
sendstring1("2. ReadManufacturerAndDeviceID\n");
ReadManufacturerAndDeviceID(id1);
/* Manufacturer ID */
sendstring1("id1->manufacturer=");
// sendchar1(char2hex(id1->manufacturer));
sendinthex1(id1->manufacturer);
sendstring1("\n");
/* Device ID (part 1) */
sendstring1("id1->device=");
//sendchar1(char2hex(id1->device));
sendinthex1(id1->device);
sendstring1("\n");
/* Device ID (part 2) */
sendstring1("id1->device=");
//sendchar1(char2hex(id1->device));
sendinthex1(id1->device);
sendstring1("\n");
/* Extended Device Information String Length */
sendstring1("id1->extendedInfoLength=");
//sendchar1(char2hex(id1->extendedInfoLength));
sendinthex1(id1->extendedInfoLength);
sendstring1("\n");
sendstring1("3.ChipErase test\n");
sendstring1("now ChipErase begin\n");
ChipErase();
sendstring1("now ChipErase end\n");
}
这个是串口的输出
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217295.jpg
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217296.jpg MEGA128与AT45DB161D的硬件连接
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217315.jpg
2http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217316.jpg
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217317.jpg 持续关注中
页:
[1]