Flash是W25Q系列的,读比较正常,写非常慢只有几K,采用了DMA来提高速度,之前也问过这个问题,一直没有得到解决,原子兄说可能是DMA的问题,我直接用Write函数写500K的数据到Flash中还是很慢,读写函数都是使用的战舰例程中的函数,DMA是我自己写的,请教一下大家可能会是哪些原因造成的速度奇慢,还有就是有没有朋友测试过Flash的读写可以达到多少?我的要求不高200K/s左右就可以了,下面是我的代码
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);
u8 SPI_FLASH_BUF[4096];
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u32 secpos;
u16 secoff;
u16 secremain;
u16 i;
secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16
secoff=WriteAddr%4096;//在扇区内的偏移
secremain=4096-secoff;//扇区剩余空间大小
LED2 = !LED2;
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_Erase_Sector(u32 Dst_Addr)
{
Dst_Addr*=4096;
SPI_FLASH_Write_Enable(); //SET WEL
SPI_Flash_Wait_Busy();
SPI_FLASH_CS=0; //使能器件
SPI2_ReadWriteByte(W25Q_SectorErase); //发送扇区擦除指令
SPI2_ReadWriteByte((u8)((Dst_Addr)>>16)); //发送24bit地址
SPI2_ReadWriteByte((u8)((Dst_Addr)>>8));
SPI2_ReadWriteByte((u8)Dst_Addr);
SPI_FLASH_CS=1; //取消片选
SPI_Flash_Wait_Busy(); //等待擦除完成
}
void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u16 pageremain;
pageremain=256-WriteAddr%256; //单页剩余的字节数
if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大于256个字节
while(1)
{
SPI_Flash_Write_Page(pBuffer,WriteAddr,pageremain);
if(NumByteToWrite==pageremain)break;//写入结束了
else //NumByteToWrite>pageremain
{
pBuffer+=pageremain;
WriteAddr+=pageremain;
NumByteToWrite-=pageremain; //减去已经写入了的字节数
if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节
else pageremain=NumByteToWrite; //不够256个字节了
}
};
}
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; //取消片选
}
还有就是我的Flash不是焊好在开发板上的而是单独的一个Flash芯片用几根铜丝把电源,地,片选,输入输出,还有时钟,焊接起来然后通过杜邦线插在相应的引脚之上的,这样会不会影响数据的传输速度呢?求教了!
|