外部FLASH AT45DB642D的读写说明及AT91SAM7X256下C实现

来源:互联网 发布:淘宝达人 微淘 编辑:程序博客网 时间:2024/05/18 14:45

AT45DB642是一种单2.7V供电,具有两种接口方式:一种为SI/SO方式,一种为I/O0-I/O7方式。这种两接口方式可使得它同时接在一个DSP和一个微控制器上。可用于数字声音、图像、程序代码及数据存储。

AT45DB642使用串行或并行方式顺序访问数据,支持SPI方式0和SPI方式3.通过片选引脚(CS)激活,通过串行输入(SI)、串行输出(SO)、串行时钟(SCK)连接。或通过并行输入、输出(I/O0-I/07)和时钟(clk)连接。SCK和CLK共用一个引脚,且向存储器提供相同时钟。


AT45DB642的存储阵列划分为三个等级:扇区、块和页。所有的编程操作基础是页-页过程。而对于擦除操作可使用块和页两种方式。


芯片操作!!

AT45DB642通过接收主控制器发来的指令来完成相应的操作。两种交互的指令是以操作码的形式实现。如读命令如下:


一个有效指令必须以CS片选信号的下降沿开始,后面伴随的是8位的指令码及要使用的BUFFER(缓存)或主存储器位置信息。CS引脚拉低后,伴随着SCK/CLK引脚时钟信号,通过SI引脚(串行方式)或I/O0-I/O7(并行方式)输入指令码及要使用的地址信息。注:所有指令、地址及数据都是先传送最高有效位方式完成传递。

 

连续读!

通过提供主存储器中首个要读取数据的地址信息,连续读命令即可根据时钟信号读出连续的数据流。之所以不需要额外的命令或地址信息,是因为AT45DB642内部集成了一个地址计数器,它在每一个时钟周期过后自动增加。若执行一个连续读操作,则需要在0x68h或e8h操作码后紧跟着输入的三个地址字节(包括24位的页地址和字节地址)及串行无关字节(串行无关为4个字节或并行无关60个字节)。伴随着无关位的正确输入,串行的SO或并行IO口会输出连续数据流。

 

FLASH整体擦除

可通过执行芯片擦除指令来完成整个FLASH区域的擦除。时序图如下:


因为是整体存储区域擦除,因此不需要地址或数据信息。

 

AT91SAM7X256下C程序实现:

void  Read_Flash_Buffer1   //基本都使用缓存的地址信息( unsigned int  BufferAddr, unsigned char *pValue,  unsigned int  ByteNum){   int i,j;unsigned int  AddrLocal;unsigned char AddrByte[3];unsigned char StatusCommand;AT91PS_SPI SPI0 = AT91C_BASE_SPI0;StatusCommand = READ_BUF1_HIGH;//parse the address to 3 address bytes for SPI chansferAddrLocal =BufferAddr;    for(i=0;i<3;i++)   AddrByte[i]=AddrLocal>>(i*8);    //send opcodewhile(!(SPI0->SPI_SR & AT91C_SPI_TDRE));AT91F_SPI_PutChar(SPI0,StatusCommand,3);for(j=0;j<10;j++);    //send start address    for(i=2;i>=0;i--){   while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));   AT91F_SPI_PutChar(SPI0,AddrByte[i],3);   for(j=0;j<8;j++);}//send one dummy bytewhile(!(SPI0->SPI_SR & AT91C_SPI_TDRE));AT91F_SPI_PutChar(SPI0,0x00,3);for(j=0;j<8;j++);    //receive data   for(i=0;i<ByteNum;i++){   while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));   AT91F_SPI_PutChar(SPI0,0x00,3);   for(j=0;j<10;j++);   while(!(SPI0->SPI_SR & AT91C_SPI_RDRF));       *(pValue+i)=AT91F_SPI_GetChar(SPI0); }}void  Write_Flash_Buffer1( unsigned int  BufferAddr, unsigned char *pValue,  unsigned int  ByteNumber){    int i,j;unsigned int  AddrLocal;unsigned char AddrByte[3];unsigned char StatusCommand;   //StatusCommand为0x84h  为实现缓冲区数据加载,一个字节操作码(缓冲区1为0x84h,缓冲区2为0x87h)                                     //伴随三个字节的地址,其中包括14个不关心位和10bit缓存区地址位。AT91PS_SPI SPI0 = AT91C_BASE_SPI0;StatusCommand = WRITE_BUF1;//parse the address to 3 address bytes for SPI transfer AddrLocal =BufferAddr;   for(i=0;i<3;i++)   AddrByte[i]=AddrLocal>>(i*8);//send opcode    while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));for(j=0;j<100;j++);AT91F_SPI_PutChar(SPI0,StatusCommand,3);    for(j=0;j<10;j++);//send start address   for(i=2;i>=0;i--){   while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));   AT91F_SPI_PutChar(SPI0,AddrByte[i],3);   for(j=0;j<8;j++);}    //send the data      //地址字节被正确写入之后,才开始进行数据的写入for(i=0;i<ByteNumber;i++){   while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));   for(j=0;j<100;j++);   AT91F_SPI_PutChar(SPI0,*(pValue+i),3);      for(j=0;j<10;j++); }//置NPCS3为高电平  while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));SPI0->SPI_TDR = 0x00|AT91C_SPI_LASTXFER;                }void Chip_Erase(void){unsigned int i;AT91PS_SPI SPI0 = AT91C_BASE_SPI0;while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));//数据发送准备完毕AT91F_SPI_PutChar(SPI0,0xC7,3);for(i=0;i<10;i++);    while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));AT91F_SPI_PutChar(SPI0,0x94,3);for(i=0;i<10;i++);while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));AT91F_SPI_PutChar(SPI0,0x80,3);for(i=0;i<10;i++);while(!(SPI0->SPI_SR & AT91C_SPI_TDRE));AT91F_SPI_PutChar(SPI0,0x9A,3);}
(文章原创,转载请声明)




原创粉丝点击