OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5718|回复: 3

关于AT45DB161连续读写的问题

[复制链接]

10

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2013-2-11
在线时间
1 小时
发表于 2015-1-2 10:11:20 | 显示全部楼层 |阅读模式
5金钱

使用了站长提供的代码http://www.openedv.com/posts/list/924.htm,

这里如果是单写单读是没问题的,比如
void flashtest()
{ uint8_t i=0;
    uint8_t write_buf[10];
    uint8_t read_buf[10];
    write_buf[0]=0x1A;
  write_buf[1]=0x19;
  write_buf[2]=0x18;
   write_buf[3]=0x17;
  write_buf[4]=0x16;
     write_buf[5]=0x15;
  write_buf[6]=0x14;
  write_buf[7]=0x13;
   write_buf[8]=0x12;
  write_buf[9]=0x11;
 Flash_Write(write_buf,1,10);

  Flash_Read(read_buf,1,10);
  for(i=0,i<10;i++)
 {
   USART_SendData(USART1, read_buf);
 }

}

但是如果发现是连续读写就会发现后面那6-10的地址数据是没写进去的,比如
void flashtest()
{ uint8_t i=0;
    uint8_t write_buf[5];
    uint8_t read_buf[10];
    write_buf[0]=0x1A;
  write_buf[1]=0x19;
  write_buf[2]=0x18;
   write_buf[3]=0x17;
  write_buf[4]=0x16;
   Flash_Write(write_buf,1,5);
 
     write_buf[4]=0x15;
  write_buf[3]=0x14;
  write_buf[2]=0x13;
   write_buf[1]=0x12;
  write_buf[0]=0x11;
 Flash_Write(write_buf,6,10);

  Flash_Read(read_buf,1,10);
  for(i=0,i<10;i++)
 {
   USART_SendData(USART1, read_buf);
 }

}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-1-2 22:46:44 | 显示全部楼层
检查Flash_Write,Flash_Read代码
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

10

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2013-2-11
在线时间
1 小时
 楼主| 发表于 2015-1-2 23:43:43 | 显示全部楼层

u8 DF_wait_busy(void)
{
 unsigned char state_reg=0x00;
 u8 retry=0;
 F_CS_ENABLE();
 SPI1_ReadWriteByte(READ_STATE_REGISTER);
 SPI1_ReadWriteByte(0x00);
 SPI1_ReadWriteByte(0x00);                       
 SPI1_ReadWriteByte(0x00);
 while((state_reg&0x80)==0&&retry<200)//重试200次
   // while(state_reg&0x80)

 {
  state_reg=SPI1_ReadWriteByte(0x00); 
  retry++;   
 }
 F_CS_DISABLE();
 if(retry>=200)return FALSE;
 else return TRUE;
}  
//将指定主存储器页的数据转入指定缓冲区
void DF_mm_to_buf(unsigned char buffer,unsigned int page)
{  
 if(DF_wait_busy()==0)return;//错误
 F_CS_ENABLE();
 if (buffer==1)SPI1_ReadWriteByte(MM_PAGE_TO_B1_XFER);  
 else SPI1_ReadWriteByte(MM_PAGE_TO_B2_XFER); 
 SPI1_ReadWriteByte((unsigned char)(page >> 6));
    SPI1_ReadWriteByte((unsigned char)(page << 2));
    SPI1_ReadWriteByte(0x00);
 F_CS_DISABLE();   

void DF_buf_to_mm(unsigned char buffer,unsigned int page)
{
 if(DF_wait_busy()==0)return;//错误
 if (page<SPI_FLASH_PageNum)
 {
  F_CS_ENABLE();
  if (buffer==1)SPI1_ReadWriteByte(B1_TO_MM_PAGE_PROG_WITH_ERASE);
  else SPI1_ReadWriteByte(B2_TO_MM_PAGE_PROG_WITH_ERASE); 
  SPI1_ReadWriteByte((unsigned char)(page>>6));
  SPI1_ReadWriteByte((unsigned char)(page<<2));
  SPI1_ReadWriteByte(0x00);
  F_CS_DISABLE();
 }

//从指定地址开始写入指定个数的数据     
void Flash_Write(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
 u16 offaddr,i;
 u32 paddr;//页地址
// SPI1_SetSpeed(SPI_SPEED_2);//设置到高速模式
 paddr=WriteAddr/SPI_FLASH_PageSize;  //得到开始写入的首页地址
 offaddr=WriteAddr%SPI_FLASH_PageSize;//得到在首页地址里的偏移
 DF_mm_to_buf(1,paddr);//将开始页数据读出到buf1    
 if(DF_wait_busy()==0)return;//错误
 F_CS_ENABLE();
 SPI1_ReadWriteByte(BUFFER_1_WRITE);//写入1缓冲区命令      
 SPI1_ReadWriteByte(0x00);//14bit 无效数据+10bit地址数据
 SPI1_ReadWriteByte((u8)(offaddr>>8));//写入在该页的偏移地址  
 SPI1_ReadWriteByte((u8)offaddr);
 for (i=0;i<NumByteToWrite;)//发送数据
 {
  SPI1_ReadWriteByte(*pBuffer);//写入一个数据
  pBuffer++;
  i++;
  if((i+offaddr)%SPI_FLASH_PageSize==0)
  {
   F_CS_DISABLE();
   DF_buf_to_mm(1,paddr); //把BUF1的内容写入主存储器
   paddr++;   
   if(paddr>=SPI_FLASH_PageNum)return; //超出了AT45DB161的范围
   DF_mm_to_buf(1,paddr); //将开始页数据读出到buf1    
   if(DF_wait_busy()==0)return;//错误
   F_CS_ENABLE();
   SPI1_ReadWriteByte(BUFFER_1_WRITE);//写入1缓冲区命令        
   SPI1_ReadWriteByte(0x00);//14bit 无效数据+10bit地址数据
   SPI1_ReadWriteByte(0x00);//设置地址到0
   SPI1_ReadWriteByte(0x00);     
  }     
 }
 F_CS_DISABLE(); 
 DF_buf_to_mm(1,paddr); //把BUF1的内容写入主存储器    
}     
 
//从指定地址开始读出指定个数的数据     
void Flash_Read(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
 u16 offaddr,i;
 u32 paddr;//页地址
 //SPI1_SetSpeed(SPI_SPEED_2);//设置到高速模式
 paddr=ReadAddr/SPI_FLASH_PageSize;  //得到开始写入的首页地址
 offaddr=ReadAddr%SPI_FLASH_PageSize;//得到在首页地址里的偏移
 DF_mm_to_buf(1,paddr);//将开始页数据读出到buf1    
 if(DF_wait_busy()==0)return;//错误
 F_CS_ENABLE();
 SPI1_ReadWriteByte(BUFFER_1_READ);//读1缓冲区命令      
 SPI1_ReadWriteByte(0x00);//14bit 无效数据+10bit地址数据
 SPI1_ReadWriteByte((u8)(offaddr>>8));//写入在该页的偏移地址  
 SPI1_ReadWriteByte((u8)offaddr);
 SPI1_ReadWriteByte(0x00); //等待
 for (i=0;i<NumByteToRead;)//读取NumByteToRead个数据
 {
  *pBuffer=SPI1_ReadWriteByte(0xff);//读取一个数据
  pBuffer++;
  i++;
  if((i+offaddr)%SPI_FLASH_PageSize==0)
  {
   F_CS_DISABLE();           
   paddr++;    
   if(paddr>=SPI_FLASH_PageNum)return; //超出了AT45DB161的范围
   DF_mm_to_buf(1,paddr); //将开始页数据读出到buf1    
   if(DF_wait_busy()==0)return;//错误
   F_CS_ENABLE();
   SPI1_ReadWriteByte(BUFFER_1_READ);//读1缓冲区命令      
   SPI1_ReadWriteByte(0x00);//14bit 无效数据+10bit地址数据
   SPI1_ReadWriteByte(0x00);//设置地址到0
   SPI1_ReadWriteByte(0x00);
   SPI1_ReadWriteByte(0x00);//等待     
  }     
 }
 F_CS_DISABLE();               
}

回复

使用道具 举报

10

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2013-2-11
在线时间
1 小时
 楼主| 发表于 2015-1-7 14:03:03 | 显示全部楼层
现在发现在两次写入中插入20MS的延时才能把问题解决,但这个不是个解决的好方法,求各位大大指教
void flashtest()
{ uint8_t a=0;
    uint8_t write_buf[5];
    uint8_t read_buf[10];
    write_buf[0]=0x3A;
 write_buf[1]=0x39;
 write_buf[2]=0x38;
  write_buf[3]=0x37;
 write_buf[4]=0x36;
Flash_Write(write_buf,1,5);
 Delayms(20);
     write_buf[0]=0x35;
 write_buf[1]=0x34;
 write_buf[2]=0x33;
  write_buf[3]=0x32;
 write_buf[4]=0x31;
Flash_Write(write_buf,6,5);


}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-27 06:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表