⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_at45db.c

📁 spi口读写串口flash AT45DB041的程序
💻 C
字号:
//详细内容:AT45DB041读写程序

//来源:侃单片机 作者:etiller
//修改:limiji 
/*正常操作电压为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 

sbit     SPI_CS             = P2^2; 
sbit     SPI_SCK             = P2^4; 
sbit     SPI_SO             = P2^6; 
sbit     SPI_SI             = P2^5; 

sbit     SPI_RESET           = P2^3; 
sbit     SPI_WP             = P2^1; 




unsigned char SPI_HostReadByte(void){ 
  unsigned char i,rByte=0; 
  
  for(i=0;i<8;i++){ 
    SPI_SCK=0; 

    SPI_SCK=1; 
    
    rByte<<=1; 
    rByte|=SPI_SO; 
  } 
  return rByte;   
} 
void SPI_HostWriteByte(unsigned char wByte){ 
  unsigned char i; 
  
  for(i=0;i<8;i++){ 
    if((wByte<<i)&0x80) {SPI_SI=1;} 
    else {SPI_SI=0;} 
      
    SPI_SCK=0; 

    SPI_SCK=1; 

  }   
} 

/*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; 
          
  SPI_CS=0;   
  SPI_HostWriteByte(0xd7); 
  i=SPI_HostReadByte(); 
  SPI_CS=1; 

  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,unsigned char *pHeader,UINT len){     
  unsigned int i;     

   while(!(AT45DB041B_StatusRegisterRead()&0x80));
  
//   while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
  SPI_CS=0;   

  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();} 
  SPI_CS=1; 

} 

/*描述:                                               */ 
/*   将指定数据写入从某个地址(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(!(AT45DB041B_StatusRegisterRead()&0x80));   
  //while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
  SPI_CS=0;   

  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);} 
  SPI_CS=1;   
  
} 
/*描述:                                               */ 
/*   将指定数据写入从某个地址(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(!(AT45DB041B_StatusRegisterRead()&0x80));
//   while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
        
  SPI_CS=0; 

  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); 
  SPI_CS=1; 

} 

/*描述:                                               */ 
/*   与上一个函数的唯一区别是不带预擦除。                         */ 

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(!(AT45DB041B_StatusRegisterRead()&0x80));
//   while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}} 
  
  SPI_CS=0; 
  SPI_HostWriteByte(0x87+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);} 
  SPI_CS=1; 

} 


void main(void){ 

  unsigned char i; 
  UCHAR data test[32]; 
//    SPI_RESET = 0;
//    SPI_WP = 0;
//   delay(2000);

//    SPI_RESET = 1;//
//    SPI_WP = 1;//取消写保护



  i=AT45DB041B_StatusRegisterRead(); 


  for(i = 0; i < 32; i++)
   {test = i + 0x20;}
  
  AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(1,0,0,test,32); 
  memset(test,0x26,32); 
  AT45DB041B_ContinuousArrayRead(0,0,test,32); 

  for(i = 0; i < 32; i++)
   {test = i + 0x10;}

  AT45DB041B_BufferToMainMemoryPageProgramWithoutBuilt_inErase(2,1,0,test,32); 
  memset(test,0x55,32); 
  AT45DB041B_ContinuousArrayRead(1,0,test,32); 

  while(1){} 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -