|
楼主 |
发表于 2007-5-9 09:07:55
|
显示全部楼层
下面是对AT45DB041的操作程序
#define F_CSSET DDRB |= (1<<0); PORTB |= (1<<0)
#define F_CS DDRB |= (1<<0); PORTB &=~(1<<0)
#define F_RSTSET DDRB |= (1<<4); PORTB |= (1<<4)
#define F_RST DDRB |= (1<<4); PORTB &=~(1<<4) //低电平复位
#define F_CHKBSY DDRB &=~(1<<5)
#define F_BSYST PINB & 0x20
/*读命令*/
/*SPI MODE 0 MODE 3*/
#define F_PGREAD 0xd2 //主存储器页读
#define F_CONRD 0xe8 //连续读
#define F_BUF1RD 0xD4 //读BUFFER1
#define F_BUF2RD 0xD6 //读BUFFER2
#define F_STREGRD 0xD7 //读状态积存器
/*写和擦除命令*/
#define F_BUF1WR 0x84 //写缓存1
#define F_BUF2WR 0x87 //写缓存2
#define BUF1TOMMEMPAGWITHERA 0x83 //缓存1到页带擦除
#define F_PAGERASE 0x81 //页擦除命令
#define F_BLKERASE 0x50 //块擦除命令
/*附加命令*/
#define MEMPAGTOBUF1 0x53 //Main Memory Page to Buffer 1 Transfer
#define MEMPAGTOBUF2 0x55 //Main Memory Page to Buffer 2 Transfer
#define SPISET DDRB |= (1<<1)|(1<<3); DDRB &=~(1<<2)
#define SCKSET PORTB |= (1<<1)
#define SCKCLR PORTB &=~(1<<1)
#define SPISO PINB & 0x04
#define MOSISET PORTB |= (1<<3)
#define MOSICLR PORTB &=~(1<<3)
/******************************************************************************/
/*正常操作电压为2.7~3.6V,实验中发现当电压超过4.25V后读出的状态字节为9A(正常 */
/*的状态字节值为9D),并且读写数据均不准确,所以应当保证卡片的供电电压不超过 */
/*4.25V。 */
/*SPI规范:Data is always clocked into the device on the rising edge of SCK a-*/
/* nd clocked out of the device on the falling edge of SCK.All instruction-*/
/* s,addresses and data are transferred with the most significant bit(MSB) */
/* first. */
/* 2005-06-02*/
/******************************************************************************/
#define UCHAR unsigned char
#define UINT unsigned int
extern void WDTO(void);
//sbit SPI_CS = P2^0;
//sbit SPI_SCK = P2^2;
//sbit SPI_SO = P2^3;
//sbit SPI_SI = P2^4;
void dt(void)
{
uchar i = 200;
while(i--);
}
unsigned char SPI_HostReadByte(void)
{
unsigned char i,rByte=0;
for(i=0;i<8;i++){
SCKCLR;
// dt();
SCKSET;
// dt();
rByte<<=1;
if(SPISO)
{
rByte |= 0x01;
}
else
rByte &= 0xfe;
// dt();
}
return rByte;
}
void SPI_HostWriteByte(unsigned char wByte){
unsigned char i;
for(i=0;i<8;i++){
if((wByte<<i)&0x80){MOSISET;}
else{MOSICLR;}
// dt();
SCKCLR;
// dt();
SCKSET;
}
}
/******************************************************************************/
/*Status Register Format: */
/* ----------------------------------------------------------------------- */
/* | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | */
/* |--------|--------|--------|--------|--------|--------|--------|--------| */
/* |RDY/BUSY| COMP | 0 | 1 | 1 | 1 | X | X | */
/* ----------------------------------------------------------------------- */
/* bit7 - 忙标记,0为忙1为不忙。 */
/* 当Status Register的位0移出之后,接下来的时钟脉冲序列将使SPI器件继续*/
/* 将最新的状态字节送出。 */
/* bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。 */
/* bit5 */
/* bit4 */
/* bit3 */
/* bit2 - 这4位用来标记器件密度,对于AT45DB041B,这4位应该是0111,一共能标记 */
/* 16种不同密度的器件。 */
/* bit1 */
/* bit0 - 这2位暂时无效 */
/******************************************************************************/
unsigned char AT45DB041B_StatusRegisterRead(void)
{
unsigned char i;
F_CS;
SPI_HostWriteByte(0xd7);
i=SPI_HostReadByte();
F_CSSET;
return i;
}
/******************************************************************************/
/*描述: */
/* When the last bit in the main memory array has been read,the device will*/
/* continue reading back at the beginning of the first page of memory.As w-*/
/* ith crossing over page boundaries,no delays will be incurred when wrapp-*/
/* ing around from the end of the array to the beginning of the array. */
/*参数: */
/* PA - 页地址,0~2047 */
/* BFA - 指定BUFFER中的起始写入地址 */
/* pHeader - 指定数据的首地址 */
/* len - 指定数据的长度 */
/******************************************************************************/
void AT45DB041B_ContinuousArrayRead(UINT PA,UINT BFA,uchar *pHeader,UINT len)
{
unsigned int i;
while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
F_CS;
SPI_HostWriteByte(0xe8);
SPI_HostWriteByte((unsigned char)(PA>>7));
SPI_HostWriteByte((unsigned char)((PA<<1)|(BFA>>8)));
SPI_HostWriteByte((unsigned char)BFA);
for(i=0;i<4;i++){SPI_HostWriteByte(0x00);}
for(i=0;i<len;i++){pHeader=SPI_HostReadByte();}
F_CSSET;
}
/******************************************************************************/
/*描述: */
/* 将指定数据写入从某个地址(0~263)开始的BUFFER中。 */
/*参数: */
/* buffer - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2 */
/* 在该指令序列中,操作码84H选择BUFFER 1,87H选择BUFFER 2 */
/* BFA - BUFFER中的起始地址,0~263 */
/* pHeader - 待存数据的头指针 */
/* len - 待存数据的长度1~264 */
/******************************************************************************/
void AT45DB041B_BufferWrite(UCHAR buffer,UINT BFA,UCHAR *pHeader,UINT len){
unsigned int i;
while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
F_CS;
switch(buffer){
case 1:SPI_HostWriteByte(0x84);break;
case 2:SPI_HostWriteByte(0x87);break;
}
SPI_HostWriteByte(0x00);
SPI_HostWriteByte((unsigned char)(BFA>>8));
SPI_HostWriteByte((unsigned char)BFA);
for(i=0;i<len;i++){SPI_HostWriteByte(pHeader);}
F_CSSET;
}
/******************************************************************************/
/*描述: */
/* 将指定数据写入从某个地址(0~263)开始的页中:包含2个动作,首先将指定数据*/
/* 写入到BUFFER 1或者BUFFER 2中,其中可以指定BUFFER中的起始写入地址,此写入*/
/* 动作不影响BUFFER中其它地址中的数据,然后再将BUFFER中的整个数据写入到某指*/
/* 定页中(带预擦除)。 */
/*参数: */
/* buffer - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2 */
/* PA - 页地址,0~2047 */
/* BFA - 指定BUFFER中的起始写入地址 */
/* pHeader - 指定数据的首地址 */
/* len - 指定数据的长度 */
/******************************************************************************/
void AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(UCHAR buffer,UINT PA,UINT BFA,UCHAR *pHeader,UINT len){
unsigned int i;
AT45DB041B_BufferWrite(buffer,BFA,pHeader,len);
while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
F_CS;
switch(buffer){
case 1:SPI_HostWriteByte(0x83);break;
case 2:SPI_HostWriteByte(0x86);break;
}
SPI_HostWriteByte((unsigned char)(PA>>7));
SPI_HostWriteByte((unsigned char)(PA<<1));
SPI_HostWriteByte(0x00);
F_CSSET;
}
/******************************************************************************/
/*描述: */
/* 与上一个函数的唯一区别是不带预擦除。 */
/******************************************************************************/
void AT45DB041B_BufferToMainMemoryPageProgramWithoutBuilt_inErase(UCHAR buffer,UINT PA,UINT BFA,UCHAR *pHeader,UINT len){
unsigned int i=0;
AT45DB041B_BufferWrite(buffer,BFA,pHeader,len);
while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
F_CS;
SPI_HostWriteByte(0x88+buffer);
SPI_HostWriteByte((unsigned char)(PA>>7));
SPI_HostWriteByte((unsigned char)(PA<<1));
SPI_HostWriteByte(0x00);
for(i=0;i<len;i++){SPI_HostWriteByte(pHeader);}
F_CSSET;
}
void buff1write(uint BFA,uchar data)
{
F_CS;
F_RSTSET;
SPI_HostWriteByte(0x84);
SPI_HostWriteByte(0);
SPI_HostWriteByte((uchar)(BFA>>8));
SPI_HostWriteByte((uchar)(BFA));
SPI_HostWriteByte(data);
F_CSSET;
}
void buff1rd(uint BFA,uchar *data)
{
F_CS;
F_RSTSET;
SPI_HostWriteByte(0xd4);
SPI_HostWriteByte(0);
SPI_HostWriteByte((uchar)(BFA>>8));
SPI_HostWriteByte((uchar)(BFA));
SPI_HostWriteByte(0);
*data = SPI_HostReadByte();
F_CSSET;
} |
|