OpenEdv-开源电子网

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

W25Q256的读写速度非常慢

[复制链接]

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
金钱
369
注册时间
2013-12-23
在线时间
32 小时
发表于 2014-4-12 13:12:05 | 显示全部楼层 |阅读模式
根据原子兄的例子实现了SPI Flash的文件系统,格式化和读写都正常,但是读写的速度非常慢,1秒钟大概只有几K的速度,下面是读写的代码和原子兄的一模一样

void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{
    u32 secpos;
    u16 secoff;
    u16 secremain;       
     u16 i; 
    secpos=WriteAddr/4096;//扇区地址 0~8192 for w25Q256
    secoff=WriteAddr%4096;//在扇区内的偏移
    secremain=4096-secoff;//扇区剩余空间大小  
    if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节
    while(1)
    {    
        SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容
        for(i=0;i<secremain;i++)//校验数据
        {
            if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除       
        }
        if(i<secremain)//需要擦除
        {
            SPI_Flash_Erase_Sector(secpos);//擦除这个扇区
            for(i=0;i<secremain;i++)       //复制
            {
                SPI_FLASH_BUF[i+secoff]=pBuffer;      
            }
            SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区 

        }else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间.                   
        if(NumByteToWrite==secremain)break;//写入结束了
        else//写入未结束
        {
            secpos++;//扇区地址增1
            secoff=0;//偏移位置为0    

               pBuffer+=secremain;  //指针偏移
            WriteAddr+=secremain;//写地址偏移       
               NumByteToWrite-=secremain;                //字节数递减
            if(NumByteToWrite>4096)secremain=4096;    //下一个扇区还是写不完
            else secremain=NumByteToWrite;            //下一个扇区可以写完了
        }    
    };         
}

void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)   
{
     u16 i;
    
    SPI_FLASH_CS=0;                            //使能器件  
    SPI2_ReadWriteByte(W25Q_ReadData);         //发送读取命令   
    SPI2_ReadWriteByte((u8)((ReadAddr)>>16));  //发送24bit地址    
    SPI2_ReadWriteByte((u8)((ReadAddr)>>8));   
    SPI2_ReadWriteByte((u8)ReadAddr);   
    for(i=0;i<NumByteToRead;i++)
    {
        pBuffer=SPI2_ReadWriteByte(0XFF);   //循环读数  
    }
    SPI_FLASH_CS=1;                            //取消片选              
}

我采用的是DMA,每次写512个字节到Flash,请教一下如此慢的速度是什么原因呢?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
金钱
369
注册时间
2013-12-23
在线时间
32 小时
 楼主| 发表于 2014-4-12 14:54:10 | 显示全部楼层
这么快就沉掉了?求解答啊
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-12 20:06:50 | 显示全部楼层
是比较慢,单你这个未免太慢了吧。。。
我们的没用DMA,直接读写,也不止你这个速度。。。
怀疑你DMA设置错了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
金钱
369
注册时间
2013-12-23
在线时间
32 小时
 楼主| 发表于 2014-4-12 21:12:53 | 显示全部楼层
谢谢原子兄我的DMA是这样设置的
  DMA_DeInit(DMA1_Channel1);                          //将DMA的通道2寄存器重设为缺省值
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;             //DMA对应的外设基地址
  DMA_InitStructure.DMA_MemoryBaseAddr = (DWORD)&ADCConvertedValue;     //内存存储基地址,对应的一个数组
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;           //DMA转换模式为SRC模式,由外设搬移到内存
  DMA_InitStructure.DMA_BufferSize = adc_buff_size;          //DMA缓存大小(设置DMA在传输时缓冲区的长度)
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    //接收一次数据后设备地址禁止后移也就是说地址保持不变(设置DMA的外设递增模式)
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;      //关闭接收一次数据后目标内存地址后移(设置DMA内存递增模式)
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;      //外设数据宽度半字
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //存储器数据宽度半字
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;               //DMA的传输模式为循环
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;           //DMA的通道拥有高优先级
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                  //非内存到内存传输
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);                  //初始化DMA通道
  
  // Enable DMA1 channel1 
  DMA_Cmd(DMA1_Channel1, ENABLE);
  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE);


其中#define adc_buff_size  6*1024
WORD ADCConvertedValue[adc_buff_size];

我的DMA之前是用在SD卡的写数据中的,使用的时候没有问题,求教原子兄我的Flash不是焊在板子上的使用几根铜丝焊上之后通过杜邦线连接不知道这样会不会影响设备工作。还有就是我的FlashU盘写数据也很慢,很奇怪的是今天白天在Xp上试了很多次都没有办法把PC上超过40k大小的文件复制到FlashU盘里面总是提示I/O操作失败,但是晚上在我自己的win7上试的时候每次都可以传进去而且1M多的文件都没有问题只是速度也非常慢,只有3点几K,还有就是我的Flash是有文件系统的用的是FATFS的文件系统
回复 支持 反对

使用道具 举报

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
金钱
369
注册时间
2013-12-23
在线时间
32 小时
 楼主| 发表于 2014-4-12 23:14:09 | 显示全部楼层
我用原子兄的FATFS的代码做工程,加了自己的写512字节的函数和DMA,发现速度没有变化,和我自己的工程的速度一样?不知道有没有人测试过原子代码的写的速度,我还发现我的代码的写速度很慢但是读速度还是比较快的
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-12 14:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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